rust/compiler/rustc_ty_utils/src
bors 7fe6f36224 Auto merge of #103491 - cjgillot:self-rpit, r=oli-obk
Support using `Self` or projections inside an RPIT/async fn

I reuse the same idea as https://github.com/rust-lang/rust/pull/103449 to use variances to encode whether a lifetime parameter is captured by impl-trait.

The current implementation of async and RPIT replace all lifetimes from the parent generics by `'static`.  This PR changes the scheme
```rust
impl<'a> Foo<'a> {
    fn foo<'b, T>() -> impl Into<Self> + 'b { ... }
}

opaque Foo::<'_a>::foo::<'_b, T>::opaque<'b>: Into<Foo<'_a>> + 'b;
impl<'a> Foo<'a> {
    // OLD
    fn foo<'b, T>() -> Foo::<'static>::foo::<'static, T>::opaque::<'b> { ... }
                             ^^^^^^^ the `Self` becomes `Foo<'static>`

    // NEW
    fn foo<'b, T>() -> Foo::<'a>::foo::<'b, T>::opaque::<'b> { ... }
                             ^^ the `Self` stays `Foo<'a>`
}
```

There is the same issue with projections. In the example, substitute `Self` by `<T as Trait<'b>>::Assoc` in the sugared version, and `Foo<'_a>` by `<T as Trait<'_b>>::Assoc` in the desugared one.

This allows to support `Self` in impl-trait, since we do not replace lifetimes by `'static` any more.  The same trick allows to use projections like `T::Assoc` where `Self` is allowed.  The feature is gated behind a `impl_trait_projections` feature gate.

The implementation relies on 2 tweaking rules for opaques in 2 places:
- we only relate substs that correspond to captured lifetimes during TypeRelation;
- we only list captured lifetimes in choice region computation.

For simplicity, I encoded the "capturedness" of lifetimes as a variance, `Bivariant` vs `Invariant` for unused vs captured lifetimes. The `variances_of` query used to ICE for opaques.

Impl-trait that do not reference `Self` or projections will have their variances as:
- `o` (invariant) for each parent type or const;
- `*` (bivariant) for each parent lifetime --> will not participate in borrowck;
- `o` (invariant) for each own lifetime.

Impl-trait that does reference `Self` and/or projections will have some parent lifetimes marked as `o` (as the example above), and participate in type relation and borrowck.  In the example above, `variances_of(opaque) = ['_a: o, '_b: *, T: o, 'b: o]`.

r? types
cc `@compiler-errors` , as you asked about the issue with `Self` and projections.
2022-11-21 12:17:03 +00:00
..
abi.rs Introduce deduced parameter attributes, and use them for deducing readonly on 2022-10-21 02:33:15 -07:00
assoc.rs Rename some OwnerId fields. 2022-10-29 20:28:38 +11:00
common_traits.rs Change InferCtxtBuilder from enter to build 2022-10-07 07:10:40 -05:00
consts.rs Use const_error_with_guaranteed more 2022-11-10 05:39:15 +00:00
errors.rs Migrate all diagnostics 2022-10-23 10:09:44 +02:00
implied_bounds.rs RPITIT placeholder items 2022-09-09 01:31:44 +00:00
instance.rs Accept TyCtxt instead of TyCtxtAt in Ty::is_* functions 2022-10-27 15:06:08 +04:00
layout.rs Factor out conservative_is_privately_uninhabited 2022-11-20 19:04:11 -06:00
layout_sanity_check.rs Factor out conservative_is_privately_uninhabited 2022-11-20 19:04:11 -06:00
lib.rs Rewrite representability 2022-10-07 09:33:46 -05:00
needs_drop.rs Accept TyCtxt instead of TyCtxtAt in Ty::is_* functions 2022-10-27 15:06:08 +04:00
representability.rs Rewrite representability 2022-10-07 09:33:46 -05:00
ty.rs Auto merge of #103491 - cjgillot:self-rpit, r=oli-obk 2022-11-21 12:17:03 +00:00