-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
52985: cause cycle err on inf trait normalization #53316
52985: cause cycle err on inf trait normalization #53316
Conversation
- If an existential type is defined, but no user code infers the concrete type behind the existential type, normalization would infinitely recurse on this existential type which is only defined in terms of itself. - Instead of raising an inf recurse error, we cause a cycle error to help highlight that the issue is that the type is only defined in terms of itself. - Three known potential improvements: - If type folding itself was exposed as a query, used by normalization and other mechanisms, cases that would cause infinite recursion would automatically cause a cycle error. - The span for the cycle error should be improved to point to user code that fails to allow inference of the concrete type of the existential type, assuming that this error occurs because no user code can allow inference the concrete type. - A mechanism to extend the cycle error with a helpful note would be nice. Currently, the error is built and maintained by src/librustc/ty/query/plumbing, with no known way to extend the information that the error gets built with.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @oli-obk (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
You could check if the call site of the outer
My first notion was "type folding can't be a query, because it tracks state in the folder". But you might be onto something there. Can you open an issue about it explaining the idea with some links to the relevant code here (also to the definition of the folder in question)?
Again, can you open an issue about this? I think it would nicely fit into the same scheme as the |
Pertaining to filing the two issues mentioned, I will do that (maybe be a couple days since I'll be away for a couple days coming up). Let me just re-post the snippet here from the original issue ticket for clarity. #![feature(existential_type)]
existential type Foo: Copy;
// make compiler happy about using 'Foo'
fn bar(x: Foo) -> Foo { x }
fn main() {
// make compiler happy about the types??
let _: Foo = unsafe { std::mem::transmute(0u8) };
} Pertaining to the first point about the span, the closest span to the A bit of background, the type normalization as part of this ICE happens as part of computing In reference to the above snippet, the span that would point at the function ( Moreover, removing the use of
If it's 1), then I think this is real issue, as we only seem to get any error when a piece of code uses If it's 2), then I suspect that the span pointing to the user of ./dev/code/rust$ rustc +stage1 ./dev/tests/data/rust_52895_ice.rs
error[E0512]: transmute called with types of different sizes
--> ./dev/tests/data/rust_52895_ice.rs:11:27
|
11 | let _: Foo = unsafe { std::mem::transmute(0u8) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: u8 (8 bits)
= note: target type: Foo (this type's size can vary)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0512`. |
I think that's the big question. It seems fine but useless to support this case. existential type Foo: std::fmt::Debug;
struct Bar(Foo);
fn foo(f: Foo) -> Bar {
Bar(f)
} is not a defining use, while struct Bar<T>(T);
fn foo(f: Foo) -> Bar<Foo> {
Bar(f)
} is a defining use. I think this is the underlying issue. Maybe we should exclude such things from being allowed to be defining uses. So we'd add an rust/src/librustc_typeck/collect.rs Line 1216 in 866a713
This might be a little too late though. Maybe the rust/src/librustc_typeck/check/writeback.rs Line 495 in c7cba3d
Not sure if we are forbidding real use cases this way, but I think all such cases should be able to work around it by moving the offending function up one level in the module hierarchy |
Looking further into
it looks like the infinite recursion defenses in normalization are a special case rather than the norm for uses of I think one of the main reasons I came up with the idea was that I was trying to figure out the lines between what is supposed to be a query vs what is supposed to be underlying machinery behind queries, per https://github.com/rust-lang/rust/tree/d767ee11616390d128853a06f5addb619e79213f/src/librustc/ty/query. The lines are still blurry to me, but I think that type folding should remain as is for now given likely effort vs win. I have filed an issue for
|
@oli-obk ok to review this current PR as is and I'll open up a new one once I look into the points of our discussion above? |
@bors r+ Yea, let's address the diagnostics improvements in further separate prs |
📌 Commit 8895e3b has been approved by |
One improvement might also be to add a span to the parent query, too |
…li-obk 52985: cause cycle err on inf trait normalization Issue: #52985 - If an existential type is defined, but no user code infers the concrete type behind the existential type, normalization would infinitely recurse on this existential type which is only defined in terms of itself. - Instead of raising an inf recurse error, we cause a cycle error to help highlight that the issue is that the type is only defined in terms of itself. - Three known potential improvements: - If type folding itself was exposed as a query, used by normalization and other mechanisms, cases that would cause infinite recursion would automatically cause a cycle error. - The span for the cycle error should be improved to point to user code that fails to allow inference of the concrete type of the existential type, assuming that this error occurs because no user code can allow inference the concrete type. - A mechanism to extend the cycle error with a helpful note would be nice. Currently, the error is built and maintained by src/librustc/ty/query/plumbing, with no known way to extend the information that the error gets built with. r? @oli-obk
☀️ Test successful - status-appveyor, status-travis |
Good perf win for keccak it seems. |
I'm not sure how this could have caused perf changes... Maybe the removal of the panic caused llvm to optimize better? |
I put nomination tags on this because it seems like it may fix the stable-to-stable regression #52701. But I am only nominating it because I want other members of the T-compiler team to weigh in about whether to backport. (My personal inclination is to not backport this to stable, and probably not to backport beta either.) |
To the best of my knowledge this was/is just a diagnostics issue. The code would never have been reasonable in the first place. So we regressed a compile-time error to an ICE and fixed it again to be an error. |
removing the beta nomination as it is already in beta by now |
Why is this nominated for stable backport? Because it is believed to fix #52701? Can anyone verify that? |
Removed the stable nomination, it's not worth the risk of a stable backport this late in the release cycle for a diagnostics regression. |
Issue: #52985
concrete type behind the existential type, normalization would
infinitely recurse on this existential type which is only defined in
terms of itself.
help highlight that the issue is that the type is only defined in terms
of itself.
normalization and other mechanisms, cases that would cause infinite recursion would
automatically cause a cycle error.
code that fails to allow inference of the concrete type of the existential type,
assuming that this error occurs because no user code can allow inference the
concrete type.
the error is built and maintained by src/librustc/ty/query/plumbing,
with no known way to extend the information that the error gets built
with.
r? @oli-obk