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

"non-defining opaque type use" with equal bound regions due to closure #112841

Closed
lcnr opened this issue Jun 20, 2023 · 4 comments · Fixed by #116891
Closed

"non-defining opaque type use" with equal bound regions due to closure #112841

lcnr opened this issue Jun 20, 2023 · 4 comments · Fixed by #116891
Labels
C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`

Comments

@lcnr
Copy link
Contributor

lcnr commented Jun 20, 2023

#![feature(type_alias_impl_trait)]
trait Trait<'a, 'b> {}
impl Trait<'_, '_> for () {}
type Tait<'a, 'b> = impl Trait<'a, 'b>;
fn fail<'a: 'b, 'b: 'a>() -> Tait<'a, 'b> {
    (|| {})()
}

results in the following but should ideally compile.

error: non-defining opaque type use in defining scope
 --> src/main.rs:6:5
  |
6 |     (|| {})()
  |     ^^^^^^^^^
  |
note: lifetime used multiple times
 --> src/main.rs:4:11
  |
4 | type Tait<'a, 'b> = impl Trait<'a, 'b>;
  |           ^^  ^^
@lcnr lcnr added C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` labels Jun 20, 2023
@lcnr lcnr changed the title non-defining opaque type use with equal bound regions non-defining opaque type use with equal bound regions due to closure Jun 20, 2023
@lcnr
Copy link
Contributor Author

lcnr commented Jun 20, 2023

I think the issue is that the closure erases regions in its signature and does not have any user type, so its generic params for the opaque aren't really sensible.

I feel like maybe closures should return their opaque constraints via https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.BorrowCheckResult.html#structfield.closure_requirements instead of dealing with them itself?

@lcnr lcnr moved this to Can do after stabilization in type alias impl trait stabilization Jun 20, 2023
@lcnr lcnr changed the title non-defining opaque type use with equal bound regions due to closure "non-defining opaque type use" with equal bound regions due to closure Jun 20, 2023
@compiler-errors
Copy link
Member

why does this fail even if a closure is just defined in-scope? 🤔

#![feature(type_alias_impl_trait)]

trait Trait<'a, 'b> {}

impl Trait<'_, '_> for () {}

type Tait<'a, 'b> = impl Trait<'a, 'b>;

fn fail<'a: 'b, 'b: 'a>() -> Tait<'a, 'b> {
    let x = || {};

    ()
}

fn main() {}

@compiler-errors
Copy link
Member

compiler-errors commented Jun 21, 2023

idk, maybe pinging @aliemjay who knows more about borrowck + closures 🤣

@aliemjay
Copy link
Member

I disagree that the OP's code should pass. Even more, I think it is a bug that we accept this:

#![feature(type_alias_impl_trait)]
trait Trait<'a, 'b> {}
impl Trait<'_, '_> for () {}
type Tait<'a, 'b> = impl Trait<'a, 'b>;
fn fail<'a: 'b, 'b: 'a>() -> Tait<'a, 'b> {
    ()
}

because it is in no way different than writing fn fail<'a>() -> Tait<'a, 'a> { ... }, which we currently reject and for a good reason.

The reason we accept these illegal defining uses of TAIT is due to a bug in

let to_universal_region = |vid, subst_regions: &mut Vec<_>| {

which evaluates lifetime equality based on the constraint graph alone, ignoring the the environment bounds. This is why this trivial change triggers the error:

fn fail<'a: 'b, 'b: 'a>() -> Tait<'a, 'b> {
+   let _ = None::<&'a &'b &'a ()>; // Now 'a and 'b are equal in the constraint graph
    ()
+   //~^ ERROR non-defining opaque type use in defining scope
}

and this explains why using closures anywhere in the body triggers the error, because it somehow adds the environmet bounds (on early-bound lifetimes exclusively) to the constraint graph.

bors added a commit to rust-lang-ci/rust that referenced this issue Oct 19, 2023
…2, r=<try>

rework opaque type region inference

fixes rust-lang#113971 Pass -> Error

fixes rust-lang#111906 ICE -> Pass
fixes rust-lang#110623 ==
fixes rust-lang#109059 ==

fixes rust-lang#112841 Pass -> Error

fixes rust-lang#110726 ICE->Error

r? `@ghost`
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 21, 2023
…2, r=<try>

rework opaque type region inference

fixes rust-lang#113971 Pass -> Error

fixes rust-lang#111906 ICE -> Pass
fixes rust-lang#110623 ==
fixes rust-lang#109059 ==

fixes rust-lang#112841 Pass -> Error

fixes rust-lang#110726 ICE->Error

r? `@ghost`
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 23, 2023
…2, r=<try>

rework opaque type region inference

fixes rust-lang#113971 Pass -> Error

fixes rust-lang#111906 ICE -> Pass
fixes rust-lang#110623 ==
fixes rust-lang#109059 ==

fixes rust-lang#112841 Pass -> Error

fixes rust-lang#110726 ICE->Error

fixes rust-lang#111935 Pass -> Error
fixes rust-lang#113916 ==

r? `@ghost`
@bors bors closed this as completed in 551abd6 Mar 28, 2024
@github-project-automation github-project-automation bot moved this from Can do after stabilization to Done in type alias impl trait stabilization Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`
Development

Successfully merging a pull request may close this issue.

3 participants