Unnamed repository; edit this file 'description' to name the repository.
Rollup merge of #157960 - aerooneqq:delegation-infers-in-generics, r=petrochenkov
delegation: add support for infers in generics This PR adds support for generating generic params for lifetimes and types/consts infers (`'_`. `_`). We support only single infers, if they are nested then we do nothing and eventually an error will be emitted after inheriting this unsound signature (i.e., `reuse foo::<Vec<_>>` is not supported). The basic idea is: ```rust fn foo<'a, 'b: 'b, T, const N: usize>() {} reuse foo::<'_, String, _> as bar; // Desugaring: fn bar<'b, const N: usize>() { foo::<'b, String, N>() } ``` So we generated params and lifetimes for provided infers. Note that in case of lifetimes we may have early and late bound lifetimes in child segment. We process only early-bound lifetimes as they are present in signature function generics (`tcx.generics_of(sig_id)`). Moreover since this PR we started to explicitly propagate early-bound lifetimes in generated delegation's call, so the warning about specifying lifetimes when late-bound lifetimes are present is suppressed for delegation segments. Next, we limit the number of processed infers with the number of generic params in the signature function, so if we have `fn foo<X, Y>() {}` and we wrote `reuse foo::<_, _, _, _>;` we will not generate 4 generic params in delegation, we will generate 2 (`X` and `Y`), two remaining infers will not be processed and this will result in an error. Considering free-to-trait reuses this PR extends the number of supported cases, as now we always generate `Self` generic param when needed: ```rust trait Trait<'a, X> { fn method<'b, const M: usize>(&self) where 'b:'b { } fn r#static<'b, Y, const B: bool>() { } } impl <'a, X> Trait<'a, X> for () { } reuse Trait::<'_, _>::method::<'_, _> as foo; reuse <_ as Trait<'_, _>>::method::<'_, _> as foo1; reuse <() as Trait<'_, _>>::method::<'_, _> as foo2; reuse <_ as Trait<'_, _>>::r#static::<_, _> as foo3; reuse <() as Trait<'_, _>>::r#static::<_, _> as foo4; reuse Trait::<'_, _>::r#static::<_, _> as foo5; // Desugaring: #[attr = Inline(Hint)] fn foo<'a, 'b, Self, X, const M: _>(self: _) -> _ where 'a:'a, 'b:'b { <Self as Trait::<'a, X>>::method::<'b, M>(self) } #[attr = Inline(Hint)] fn foo1<'a, 'b, Self, X, const M: _>(self: _) -> _ where 'a:'a, 'b:'b { <Self as Trait::<'a, X>>::method::<'b, M>(self) } #[attr = Inline(Hint)] fn foo2<'a, 'b, X, const M: _>(self: _) -> _ where 'a:'a, 'b:'b { <() as Trait::<'a, X>>::method::<'b, M>(self) } #[attr = Inline(Hint)] fn foo3<'a, Self, X, Y, const B: _>() -> _ where 'a:'a { <Self as Trait::<'a, X>>::r#static::<Y, B>() } #[attr = Inline(Hint)] fn foo4<'a, X, Y, const B: _>() -> _ where 'a:'a { <() as Trait::<'a, X>>::r#static::<Y, B>() } #[attr = Inline(Hint)] fn foo5<'a, Self, X, Y, const B: _>() -> _ where 'a:'a { <Self as Trait::<'a, X>>::r#static::<Y, B>() } ``` Note that we generated `Self` in `foo5` reuse. With that done the error about self-type specification is removed. Finally this PR greatly simplifies generic args for signature inheritance generation code. Part of rust-lang/rust#118212. r? @petrochenkov
Jacob Pratt 5 weeks ago
parent d6888b3 · parent 8e61983 · commit 02b6ff1
0 files changed, 0 insertions, 0 deletions