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

Make sure that outer opaques capture inner opaques's lifetimes even with precise capturing syntax #131789

Merged
merged 1 commit into from
Oct 20, 2024

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Oct 16, 2024

When lowering an opaque, we must capture and duplicate all of the lifetimes in the opaque's bounds to correctly lower the opaque's bounds. We do this even if the lifetime is not captured according to the + use<> precise capturing bound; in that case, we will later reject that captured lifetime. For example, Given an opaque like impl Sized + 'a + use<>, we will still duplicate 'a but later error that it is not mentioned in the use<> bound.

The current heuristic was not properly handling cases like:

//@ edition: 2024
fn foo<'a>() -> impl Trait<Assoc = impl Trait2> + use<> {}

Which forces the outer impl Trait to capture 'a since impl Trait2 implicitly captures 'a due to the new lifetime capture rules for edition 2024. We were only capturing lifetimes syntactically mentioned in the bounds. (Note that this still is an error; we just need to capture 'a so it is handled later in the compiler correctly -- hence the ICE in #131769 where a late-bound lifetime was being referenced outside of its binder).

This PR reworks the way we collect lifetimes to capture and duplicate in AST lowering to fix this.

Fixes #131769

@rustbot
Copy link
Collaborator

rustbot commented Oct 16, 2024

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@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 Oct 16, 2024
Copy link
Member

@fmease fmease left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me. r=me with nitpicks addressed at your leisure unless you want sb. else to review it.

Yesterday I finally spent quite some time carefully reading up on the way we deal with opaque types, namely AST lowering, the whole parameter duplication thing, variances of opaques and member constraints.

cc @cjgillot (#129383)

compiler/rustc_ast_lowering/src/lib.rs Outdated Show resolved Hide resolved
compiler/rustc_ast_lowering/src/lifetime_collector.rs Outdated Show resolved Hide resolved
_ => false,
})
{
for (ident, id, _) in self.resolver.extra_lifetime_params(opaque_ty_node_id) {
Copy link
Member

@fmease fmease Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right so IIUC, we can no longer take the extra lifetime params because if we did, they would no longer be available when lowering any nested opaques (here: impl Sized) after having lowered any overarching opaques (here: impl IntoIterator<Item = impl Sized>).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we need to be able to access these extra lifetimes both when walking the bounds of the parent opaque, and also lowering the child opaque itself. I have no idea why we were using take before, it's not like we really enforced it.

@fmease fmease assigned fmease and unassigned TaKO8Ki Oct 19, 2024
@compiler-errors
Copy link
Member Author

@bors r=fmease

@bors
Copy link
Contributor

bors commented Oct 19, 2024

📌 Commit 70746d0 has been approved by fmease

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-review Status: Awaiting review from the assignee but also interested parties. labels Oct 19, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 19, 2024
…iaskrgr

Rollup of 12 pull requests

Successful merges:

 - rust-lang#116863 (warn less about non-exhaustive in ffi)
 - rust-lang#127675 (Remove invalid help diagnostics for const pointer)
 - rust-lang#131772 (Remove `const_refs_to_static` TODO in proc_macro)
 - rust-lang#131789 (Make sure that outer opaques capture inner opaques's lifetimes even with precise capturing syntax)
 - rust-lang#131795 (Stop inverting expectation in normalization errors)
 - rust-lang#131920 (Add codegen test for branchy bool match)
 - rust-lang#131921 (replace STATX_ALL with (STATX_BASIC_STATS | STATX_BTIME) as former is deprecated)
 - rust-lang#131925 (Warn on redundant `--cfg` directive when revisions are used)
 - rust-lang#131931 (Remove unnecessary constness from `lower_generic_args_of_path`)
 - rust-lang#131932 (use tracked_path in rustc_fluent_macro)
 - rust-lang#131936 (feat(rustdoc-json-types): introduce rustc-hash feature)
 - rust-lang#131939 (Get rid of `OnlySelfBounds`)

Failed merges:

 - rust-lang#131181 (Compiletest: Custom differ)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit bc22740 into rust-lang:master Oct 20, 2024
6 checks passed
@rustbot rustbot added this to the 1.84.0 milestone Oct 20, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Oct 20, 2024
Rollup merge of rust-lang#131789 - compiler-errors:capture-more, r=fmease

Make sure that outer opaques capture inner opaques's lifetimes even with precise capturing syntax

When lowering an opaque, we must capture and duplicate all of the lifetimes in the opaque's bounds to correctly lower the opaque's bounds. We do this *even if* the lifetime is not captured according to the `+ use<>` precise capturing bound; in that case, we will later reject that captured lifetime. For example, Given an opaque like `impl Sized + 'a + use<>`, we will still duplicate `'a` but later error that it is not mentioned in the `use<>` bound.

The current heuristic was not properly handling cases like:

```
//@ edition: 2024
fn foo<'a>() -> impl Trait<Assoc = impl Trait2> + use<> {}
```

Which forces the outer `impl Trait` to capture `'a` since `impl Trait2` *implicitly* captures `'a` due to the new lifetime capture rules for edition 2024. We were only capturing lifetimes syntactically mentioned in the bounds. (Note that this still is an error; we just need to capture `'a` so it is handled later in the compiler correctly -- hence the ICE in rust-lang#131769 where a late-bound lifetime was being referenced outside of its binder).

This PR reworks the way we collect lifetimes to capture and duplicate in AST lowering to fix this.

Fixes rust-lang#131769
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.

ICE: escaping bound vars in predicate
5 participants