-
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
MIR dead code analysis affects TAIT inference #99490
Comments
I want to fix this but have no idea how I would begin, lol. |
I'm fairly certain we don't run simplify cfg on MIR before doing borrowck. Borrowck still does enough dataflow analysis to realize that everything after the panic is dead. I guess typeck will to it correctly... so maybe we have to return all hidden types from typeck and seed the borrowck hidden types with it (so that borrowck only fills in the lifetimes instead of also figuring out the types) |
doesn't this run before borrowck: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_mir_transform/lib.rs.html#244 |
Oh... huh... i was sure I've seems dead code in borrowck before, guess not. Either way, the "grab things from typeck" plan would work here, too |
I'm finding a few issues with this strategy. Firstly, since the typeck results have their non-late regions erased, I'm not exactly sure how we're supposed to use the erased hidden type to seed the borrowck hidden types. One thought I had was that we could capture the opaque type key and hidden type's lifetimes in a binder, like generator interior does to avoid being erased in the typeck resuls. But I found a problem that it's not even guaranteed there's a useful relationship between the regions present in the hidden type and those present in the substs of the opaque key... |
Yes, that's why we actually need to do opaque type resolution in borrowck. The typeck hidden type would only be used as the initial value for the opaque types constrained by this item. All erased regions can be replaced by inference vars (which is effectively what borrowck does for all regions in the MIR). Then, the each time the hidden type is constrained again, the inference lifetimes from the seed hidden type are compared against the lifetimes of the new hidden type. If the only constraining happens in dead code, you'll end up with a lifetime error (unless the type has no lifetimes) |
I'm mostly writing this out for my understanding, and to express some continuing confusion. So I've gathered that we handle opaque types in two stages during borrowck -- first during Between those two places, I have no idea where we'd put this new logic. I don't think we can just stick typeck's erased copy of these hidden types into the On the other hand, I don't know where in |
You have identity substs, so yea, we could do it at the end where we convert everything to identity substs anyway |
yup i can see this being the right way to do it. working on it now. |
This sounds straight forward, and the implementation is, but now libcore doesn't compile anymore, because lifetime resolution is already done and thus the lifetimes of the identity-substituted type can't be equated to the other types that were already found. Maybe we should only assert at the end that the hidden type found by typeck is the same as the one found by borrowck (modulo lifetimes). If borrowck found no hidden type, but typeck did, use the typeck type (with erased regions) to check that all other hidden types that were found by other functions at least match (again, modulo regions) |
Yeah, I was curious if we could move all of this logic into |
Yea, that seems more reasonable. Started doing that an hour ago and ironically I immediately found dead code in the opaque type processing logic 😆 |
Check hidden types in dead code fixes rust-lang#99490 r? `@compiler-errors` best reviewed commit by commit
Given the code:
If you run the code, you can see that the compiler ends up "successfully" inferencing
Tait = One
and succeeding compilation, even though upon visual inspection, the compiler should be raising an error sincefn two
should cause the conflicting inferenceTait = Two<()>
.The key here is the
todo!()
macro, which causes theSimplifyCfg
MIR pass to remove MIR that actually causes us to make this second inference.Is this expected? How would we even change this behavior, since it would require us to disentangle TAIT inference from borrowck..?
The text was updated successfully, but these errors were encountered: