-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Instantiate closure synthetic substs in root universe #112399
Instantiate closure synthetic substs in root universe #112399
Conversation
@@ -189,6 +189,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||
pub fn errors_reported_since_creation(&self) -> bool { | |||
self.tcx.sess.err_count() > self.err_count_on_creation | |||
} | |||
|
|||
pub fn next_root_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { |
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 put this in FnCtxt
since I want to discourage it from being used in non-typeck places. I could also probably leave a FIXME to remove this once we model universes more faithfully. Also, I could give this a scarier name.
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.
think it's fine for this to not be too scary given that misusing it accepts strictly less code, would like some short comment about what this means though
f0aa647
to
e3b499f
Compare
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.
r=me
please figure out a test where we hit the underlying issue which does not rely on closures, can hand that to me if stuck
@@ -189,6 +189,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||
pub fn errors_reported_since_creation(&self) -> bool { | |||
self.tcx.sess.err_count() > self.err_count_on_creation | |||
} | |||
|
|||
pub fn next_root_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { |
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.
think it's fine for this to not be too scary given that misusing it accepts strictly less code, would like some short comment about what this means though
hitting this issue after the PR lands is incredibly difficult as the types of all locals are gathered at the start of typeck, so they all live in the root universe. Can always go back to the underlying issue if it crops up later via crater or sth @bors r+ rollup |
…t-universe, r=lcnr Instantiate closure synthetic substs in root universe In the UI test example, we end up generalizing an associated type (something like `<Map<Option<i32>, [closure upvars=?0]> as IntoIterator>::Item` generalizes into `<Map<Option<i32>, [closure upvars=?1]> as IntoIterator>::Item`) then assigning it to itself, emitting an alias-relate goal. This trivially holds via one of the normalizes-to candidates, instead of relating substs, so when closure analysis eventually sets `?0` to the actual upvars, `?1` never gets constrained. This ends up being reported as an ambiguity error during writeback. Instead, we can take advantage of the fact that we *know* the closure substs live in the root universe. This will prevent them being generalized, since they always can be named, and the alias-relate above never gets emitted at all. We can probably do this to a handful of other `next_ty_var` calls in typeck for variables that are clearly associated with the body of the program, but I wanted to limit this for now. Eventually, if we end up representing universes more faithfully like a tree or whatever, we can remove this and turn it back to just a call to `next_ty_var`. Note: This is incredibly order-dependent -- we need to be assigning a type variable that was created *before* the closure substs, and we also need to actually have an unnormalized type at the time of the assignment. This currently seems easiest to trigger during call argument analysis just due to the fact that we instantiate the call's substs, normalize, THEN check args. r? `@lcnr`
…t-universe, r=lcnr Instantiate closure synthetic substs in root universe In the UI test example, we end up generalizing an associated type (something like `<Map<Option<i32>, [closure upvars=?0]> as IntoIterator>::Item` generalizes into `<Map<Option<i32>, [closure upvars=?1]> as IntoIterator>::Item`) then assigning it to itself, emitting an alias-relate goal. This trivially holds via one of the normalizes-to candidates, instead of relating substs, so when closure analysis eventually sets `?0` to the actual upvars, `?1` never gets constrained. This ends up being reported as an ambiguity error during writeback. Instead, we can take advantage of the fact that we *know* the closure substs live in the root universe. This will prevent them being generalized, since they always can be named, and the alias-relate above never gets emitted at all. We can probably do this to a handful of other `next_ty_var` calls in typeck for variables that are clearly associated with the body of the program, but I wanted to limit this for now. Eventually, if we end up representing universes more faithfully like a tree or whatever, we can remove this and turn it back to just a call to `next_ty_var`. Note: This is incredibly order-dependent -- we need to be assigning a type variable that was created *before* the closure substs, and we also need to actually have an unnormalized type at the time of the assignment. This currently seems easiest to trigger during call argument analysis just due to the fact that we instantiate the call's substs, normalize, THEN check args. r? ``@lcnr``
Rollup of 7 pull requests Successful merges: - rust-lang#112163 (fix: inline `predicate_may_hold_fatal` and remove expect call in it) - rust-lang#112399 (Instantiate closure synthetic substs in root universe) - rust-lang#112443 (Opportunistically resolve regions in new solver) - rust-lang#112535 (reorder attributes to make miri-test-libstd work again) - rust-lang#112579 (Fix building libstd documentation on FreeBSD.) - rust-lang#112639 (Fix `dead_code_cgu` computation) - rust-lang#112642 (Handle interpolated literal errors) r? `@ghost` `@rustbot` modify labels: rollup
In the UI test example, we end up generalizing an associated type (something like
<Map<Option<i32>, [closure upvars=?0]> as IntoIterator>::Item
generalizes into<Map<Option<i32>, [closure upvars=?1]> as IntoIterator>::Item
) then assigning it to itself, emitting an alias-relate goal. This trivially holds via one of the normalizes-to candidates, instead of relating substs, so when closure analysis eventually sets?0
to the actual upvars,?1
never gets constrained. This ends up being reported as an ambiguity error during writeback.Instead, we can take advantage of the fact that we know the closure substs live in the root universe. This will prevent them being generalized, since they always can be named, and the alias-relate above never gets emitted at all.
We can probably do this to a handful of other
next_ty_var
calls in typeck for variables that are clearly associated with the body of the program, but I wanted to limit this for now. Eventually, if we end up representing universes more faithfully like a tree or whatever, we can remove this and turn it back to just a call tonext_ty_var
.Note: This is incredibly order-dependent -- we need to be assigning a type variable that was created before the closure substs, and we also need to actually have an unnormalized type at the time of the assignment. This currently seems easiest to trigger during call argument analysis just due to the fact that we instantiate the call's substs, normalize, THEN check args.
r? @lcnr