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

defining type-alias-impl-trait inside closures is broken #105498

Closed
aliemjay opened this issue Dec 9, 2022 · 2 comments · Fixed by #116891
Closed

defining type-alias-impl-trait inside closures is broken #105498

aliemjay opened this issue Dec 9, 2022 · 2 comments · Fixed by #116891
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@aliemjay
Copy link
Member

aliemjay commented Dec 9, 2022

All these test cases should pass:

#![feature(type_alias_impl_trait)]
trait Cap<'a> {}
impl<T> Cap<'_> for T {}

mod case1 {
    type MyStr<'x> = impl Sized + super::Cap<'x>;
    fn case1<'s>(s: &'s str) {
        || { let _: MyStr<'s> = s; };
        //~^ ERROR unconstrained opaque type
    }
}

mod case2 {
    type MyStr<'x> = impl Sized + super::Cap<'x> + 'x; // note `+ 'x`
    fn case2<'s>() {
        let _: MyStr<'s> = "";  // inferred ty: &'s str
        || -> MyStr<'s> { "" }; // inferred ty: &'static str
        //~^ ERROR concrete type differs from previous defining opaque type use
    }
}

mod case3 {
    type MyStr<'x> = impl Sized + super::Cap<'x>;
    fn case3<'s>() {
        |s: &'s str| { let _: MyStr<'s> = s; };
        //~^ ERROR captures lifetime that does not appear in bounds
    }
}

The current algorithm for member constraints is broken when used in closures because it assumes the relations between universal regions to be known, which is not true when we're borrow-checking closures.

@rustbot label C-bug T-types F-type_alias_impl_trait A-borrow-checker

@rustbot rustbot added A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue. labels Dec 9, 2022
@lcnr
Copy link
Contributor

lcnr commented Dec 13, 2023

is the correct fix here to propagate member constraints to the function and only check them there?

@aliemjay
Copy link
Member Author

is the correct fix here to propagate member constraints to the function and only check them there?

Member constraints are more complicated than regular outlives constraints in that they require the complete constraint graph between the "source" and "choice" regions in order to pick the right choice. When one of the regions is "external" to the closure we get surprising results like in this issue.

I believe this is impossible to fix unless we borrow check the closure and the parent fn in a single context like we did with the good old HIR borrowck, but that in turn is complicated. This is why I don't bother and suggest to disallow such defining uses. See #116891 (comment) for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants