-
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
Fix tuple element tys returned from sized_conditions()
#121726
Conversation
8652f5d
to
c107f12
Compare
Please see my comment here: #121443 (comment) . Would appreciate if you can validate if this is the right approach. If it is, I can fix the failing/ICEing tests caused by this change. |
This comment has been minimized.
This comment has been minimized.
They are meant to only look at the last type in structs and tuples (the "tail"), as that is the only thing that decides the sizedness of the entire type. This is sufficient in theory, because unsized types anywhere but the last field are unsupported and a hard error in wfcheck. Of course that doesn't help code that relies on wfcheck having bailed out already. Maybe we should move such checks into stuff the |
Thanks. I'll implement according to your suggestions. |
Those were just thoughts, I'm not sure this is a straightforward change. Tho the deduplication should probably be done on its own anyway |
Yeah, we can do the dedup in a separate PR. I am not super familiar with the trait selection code, so let me go through it and see what I can do. |
c107f12
to
8b52984
Compare
I have spent some time familiarizing myself with trait selection code and analyzed #21443 again. What is happening in the issue is:
Based on the above analysis, the fix in Now I have pushed a new commit in which rust/compiler/rustc_trait_selection/src/traits/select/mod.rs Lines 1270 to 1279 in f7cb53e
Err entry to the selection cache.
#21443 is now fixed, the ICEs in codegen we saw earlier are gone and all the tests are green. @oli-obk Please let me know what you think and whether this approach can be viable at all. |
@rustbot label -S-waiting-on-author +S-waiting-on-review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is correct. I am worried there is something this will break out in the wild, but I think it's different from how we accept fn() -> str
function pointers in the type system, even if they can't be constructed or used.
@rust-lang/types can you think of any issues with checking that in order for a tuple to be sized, all its fields need to be sized (instead of just checking the last field)
Checking that all tuple fields are From what I can tell the root issue here is that we do not abort evaluation even though typeck failed. I don't know why this is the case but both |
it's not a typeck error, but a wfcheck error, and that happens in a separate query invocation tree. There is no way to carry information from wfcheck to typeck without causing lots of cycles. |
why does typeck not check that the return type is well-formed? We should check that in typeck as well 🤔 |
Not well formed, but typeck does check that the the return type is sized. It does so by adding a rust/compiler/rustc_hir_typeck/src/lib.rs Line 256 in 7606c13
rust/compiler/rustc_hir_typeck/src/lib.rs Line 266 in 7606c13
Unfortunately this check passes because it finds the |
We could still try this scheme (and then make typeck do the wfchecks instead of wfcheck) |
Sorry, I didn't fully understand what you meant😟(mostly due to my new-ness to this area). wfcheck doesn't seem to be doing any manual checks for tuples even now. All it does is add a rust/compiler/rustc_trait_selection/src/traits/wf.rs Lines 627 to 633 in f7cb53e
Sized trait predicate for the tuple type from being added to the cache.
Please elaborate a bit more on what you had in mind and I'll investigate further. |
that's fine. What lcnr was proposing was to liberally add additional |
Instead of returning the type of only the last element we return the types of all elements. Without it in some situations we were allowing typeck to succeed for tuples which have an unsized element at a non-last position.
8b52984
to
cf7a036
Compare
If we only register a |
I assumed that |
And I should add, the |
how did we end up getting an error then? We do get the error |
if a type is not well-formed, we can probably prove all kinds of broken things for it. So the |
That said, ideally we'd just do this properly with the change that you did here, but that is only part of the story, there may be other ways in which those tuples (or other types) may not be well formed, and cause ICEs subsequently. That said, let's at least check the claim that this change is a perf issue @bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
Yes it did. The processing of rust/compiler/rustc_trait_selection/src/traits/wf.rs Lines 627 to 633 in f7cb53e
Sized obligations for all non-last fields which would be T: Sized in our case.
And this Ideally the failure of a child obligations should add an The only place where something like this occurs is in |
Yes, this error is the |
We don't actually need Are you saying that the implied |
True. The immediate need is only to have typeck fail. We don't really care about
And all of this is happening regardless of the presence of But this given me an idea - what if we made typeck to check for Now that it is slowly dawning on me, isn't that what you were suggesting originally? Or may be lcnr suggested that? |
That means Or, transitively, If so, |
We imply that @oli-obk, what kind of cycles do you get if you also taint the MIR if wfcheck failed? |
Mostly const eval cycles iirc, but let's actually try it and document it xD Ah, but also |
Just curious. What does |
The situation right now is that |
Jup, I prefer the other PR. Thanks! |
Instead of returning the type of the last element we flip it around and return types of all elements except the last one. This matches the the constraint on tuple types which says that only the last element can be unsized.
Edit
Returning all elements except the last was a mistake. We now return all the elements.
Fixes #121443