Rollup merge of #109277 - spastorino:new-rpitit-14, r=compiler-errors
Fix generics_of for impl's RPITIT synthesized associated type The only useful commit is the last one. This makes `generics_of` for the impl side RPITIT copy from the trait's associated type and avoid the fn on the impl side which was previously wrongly used. This solution is better but we still need to fix resolution of the generated generics. r? ``@compiler-errors``
This commit is contained in:
commit
d86fd83ef6
13 changed files with 60 additions and 12 deletions
|
@ -3152,8 +3152,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
debug!("impl_trait_ty_to_ty: generics={:?}", generics);
|
debug!("impl_trait_ty_to_ty: generics={:?}", generics);
|
||||||
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
|
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||||
if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
|
// We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
|
||||||
// Our own parameters are the resolved lifetimes.
|
// since return-position impl trait in trait squashes all of the generics from its source fn
|
||||||
|
// into its own generics, so the opaque's "own" params isn't always just lifetimes.
|
||||||
|
if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
|
||||||
|
{
|
||||||
|
// Resolve our own lifetime parameters.
|
||||||
let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
|
let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
|
||||||
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
|
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
|
||||||
self.ast_region_to_region(lifetime, None).into()
|
self.ast_region_to_region(lifetime, None).into()
|
||||||
|
|
|
@ -396,6 +396,8 @@ fn associated_type_for_impl_trait_in_impl(
|
||||||
impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id));
|
impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id));
|
||||||
|
|
||||||
// Copy generics_of the trait's associated item but the impl as the parent.
|
// Copy generics_of the trait's associated item but the impl as the parent.
|
||||||
|
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl
|
||||||
|
// generics.
|
||||||
impl_assoc_ty.generics_of({
|
impl_assoc_ty.generics_of({
|
||||||
let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
|
let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
|
||||||
let trait_assoc_parent_count = trait_assoc_generics.parent_count;
|
let trait_assoc_parent_count = trait_assoc_generics.parent_count;
|
||||||
|
@ -404,16 +406,10 @@ fn associated_type_for_impl_trait_in_impl(
|
||||||
let parent_generics = tcx.generics_of(impl_def_id);
|
let parent_generics = tcx.generics_of(impl_def_id);
|
||||||
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
||||||
|
|
||||||
let mut impl_fn_params = tcx.generics_of(impl_fn_def_id).params.clone();
|
|
||||||
|
|
||||||
for param in &mut params {
|
for param in &mut params {
|
||||||
param.index = param.index + parent_count as u32 + impl_fn_params.len() as u32
|
param.index = param.index + parent_count as u32 - trait_assoc_parent_count as u32;
|
||||||
- trait_assoc_parent_count as u32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_fn_params.extend(params);
|
|
||||||
params = impl_fn_params;
|
|
||||||
|
|
||||||
let param_def_id_to_index =
|
let param_def_id_to_index =
|
||||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
// edition:2021
|
// edition:2021
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/lifetime-mismatch.rs:3:12
|
--> $DIR/lifetime-mismatch.rs:5:12
|
||||||
|
|
|
|
||||||
LL | #![feature(async_fn_in_trait)]
|
LL | #![feature(async_fn_in_trait)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
@ -8,7 +8,7 @@ LL | #![feature(async_fn_in_trait)]
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
|
error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
|
||||||
--> $DIR/lifetime-mismatch.rs:12:17
|
--> $DIR/lifetime-mismatch.rs:14:17
|
||||||
|
|
|
|
||||||
LL | async fn foo<'a>(&self);
|
LL | async fn foo<'a>(&self);
|
||||||
| ---- lifetimes in impl do not match this method in trait
|
| ---- lifetimes in impl do not match this method in trait
|
21
tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
Normal file
21
tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/lifetime-mismatch.rs:5:12
|
||||||
|
|
|
||||||
|
LL | #![feature(async_fn_in_trait)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
|
||||||
|
--> $DIR/lifetime-mismatch.rs:14:17
|
||||||
|
|
|
||||||
|
LL | async fn foo<'a>(&self);
|
||||||
|
| ---- lifetimes in impl do not match this method in trait
|
||||||
|
...
|
||||||
|
LL | async fn foo(&self) {}
|
||||||
|
| ^ lifetimes do not match method in trait
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0195`.
|
|
@ -1,4 +1,6 @@
|
||||||
// edition:2021
|
// edition:2021
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
// edition:2021
|
// edition:2021
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
||||||
--> $DIR/trait-more-generics-than-impl.rs:11:11
|
--> $DIR/trait-more-generics-than-impl.rs:14:11
|
||||||
|
|
|
|
||||||
LL | fn bar<T>() -> impl Sized;
|
LL | fn bar<T>() -> impl Sized;
|
||||||
| - expected 1 type parameter
|
| - expected 1 type parameter
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
||||||
|
--> $DIR/trait-more-generics-than-impl.rs:14:11
|
||||||
|
|
|
||||||
|
LL | fn bar<T>() -> impl Sized;
|
||||||
|
| - expected 1 type parameter
|
||||||
|
...
|
||||||
|
LL | fn bar() -> impl Sized {}
|
||||||
|
| ^ found 0 type parameters
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0049`.
|
|
@ -1,3 +1,6 @@
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
// edition: 2021
|
// edition: 2021
|
||||||
|
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
|
||||||
|
// revisions: current next
|
||||||
|
|
||||||
#![feature(return_position_impl_trait_in_trait)]
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue