Skip to content
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

Merged
merged 1 commit into from
Jun 16, 2023

Conversation

compiler-errors
Copy link
Member

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 7, 2023
@@ -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> {
Copy link
Member Author

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.

Copy link
Contributor

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

@rust-cloud-vms rust-cloud-vms bot force-pushed the closure-substs-root-universe branch from f0aa647 to e3b499f Compare June 7, 2023 18:28
Copy link
Contributor

@lcnr lcnr left a 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> {
Copy link
Contributor

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

@lcnr lcnr added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 8, 2023
@lcnr
Copy link
Contributor

lcnr commented Jun 15, 2023

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

@bors
Copy link
Contributor

bors commented Jun 15, 2023

📌 Commit e3b499f has been approved by lcnr

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 15, 2023
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jun 16, 2023
…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`
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Jun 16, 2023
…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``
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 16, 2023
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
@bors bors merged commit b41db84 into rust-lang:master Jun 16, 2023
@rustbot rustbot added this to the 1.72.0 milestone Jun 16, 2023
@compiler-errors compiler-errors deleted the closure-substs-root-universe branch August 11, 2023 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants