-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
overflow => generics that produce trans errors depending on type parameters #32498
Comments
triage: I-nominated |
cc @aturon |
This is possible even without specialization. At least, it used to be with the old |
I made a mistake: the first example doesn't actually require specialization, and the simplified version I edited into the original post works the same way on stable. Though I think it may be more difficult to fix in the presence of specialization: the only reason |
triage: P-high to investigate |
So, I see the first example as a case that we should ultimately try to catch and give a better error for (as we do for more direct circular structs). But I don't think it's terribly urgent, personally. For the second case: I suspect that this is fundamental. That is, the proof search for traits fundamentally relies on an overflow cutoff to avoid infinite loops, and the fact that specialization lets you dispatch on types will always mean that you can selectively create these overflowing situations. I see the "blame" here as mostly the fact that the trait system can fail due to overflow, but that's inevitable in having as powerful of a system as we do. I'm going to renominate for triage of the bug listed in the top comment, which we could try to provide a better error for. I suggest that this is P-low, however. triage: I-nominated |
triage: P-low @aturon's summary seems accurate. |
I got the same while playing around with Rust: struct L<T> {
n: Option<T>,
}
type L8<T> = L<L<L<L<L<L<L<L<T>>>>>>>>;
type L64<T> = L8<L8<L8<L8<T>>>>;
fn main() {
use std::mem::size_of;
// This prints "128: 1":
println!("128: {}", size_of::<L64<L64<()>>>());
// This line does not compile: error: overflow representing the type std::option::Option<()>
println!("129: {}", size_of::<L<L64<L64<()>>>>());
} While something like this might not make much sense in real programs I thought it might be useful to you to have a minimal source that demonstrates the problem. Option is not needed here, but it cuts down the amount of "recursivity" in half. So it seems there is some kind of limit of 256 levels when building a struct. I wonder if it's possible to reach the limit with real-life programs. Most recursive or complex structs hold pointers, not actual data, so I guess it's not a problem for most people. |
…mulacrum Add a regression test for rust-lang#32498 [This](rust-lang#32498 (comment)) test mentioned at issue rust-lang#32498 now passes. This PR adds this regression test.
Rollup of 11 pull requests Successful merges: - rust-lang#80523 (#[doc(inline)] sym_generated) - rust-lang#80920 (Visit more targets when validating attributes) - rust-lang#81720 (Updated smallvec version due to RUSTSEC-2021-0003) - rust-lang#81891 ([rustdoc-json] Make `header` a vec of modifiers, and FunctionPointer consistent) - rust-lang#81912 (Implement the precise analysis pass for lint `disjoint_capture_drop_reorder`) - rust-lang#81914 (Fixing bad suggestion for `_` in `const` type when a function rust-lang#81885) - rust-lang#81919 (BTreeMap: fix internal comments) - rust-lang#81927 (Add a regression test for rust-lang#32498) - rust-lang#81965 (Fix MIR pretty printer for non-local DefIds) - rust-lang#82029 (Use debug log level for developer oriented logs) - rust-lang#82056 (fix ice (rust-lang#82032)) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
deavid's minimized reproduction compiles and runs for me (Rust 1.53). comex's original example still fails, but the error messages are different, and it's no longer possible to bypass the error by commenting out usage. Since this bug report is less along the lines of "types should be allowed to recurse indefinitely" and more along the lines of "too-large types shouldn't require usage in order to be rejected", I suspect this can be closed. However, a UI test might be nice. |
Closing this based on the [comment](#32498 (comment) |
In which we sneakily define a type that contains itself:
(EDIT: Actually, this one didn't depend on specialization. There was previously a default impl of
Tr2
not depending onTr
, but it wasn't necessary. The second one does seem to depend on it.)produces:
This error comes from trans, and it goes away if either the call to
func
orfunc
's usage ofS<T>
is commented out. In other words,func
claims to allow instantiation with any type but actually supports no types. (By adding more specializations it could be made to support only certain types.)A similar issue is when overflow occurs while determining whether a given specialization applies:
This happens to compile, but if the
u32
in main is changed tou64
, I get:Is this a known consequence of specialization? I haven't seen it discussed. It seems to violate Rust's normal policy of type-safe generics, and I'm not sure what a rule to prevent it upfront would look like (especially considering that the patterns can in some cases be split across multiple crates).
The text was updated successfully, but these errors were encountered: