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

Fix generics_of for impl's RPITIT synthesized associated type #109277

Merged
merged 2 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3141,8 +3141,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

debug!("impl_trait_ty_to_ty: generics={:?}", generics);
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
// Our own parameters are the resolved lifetimes.
// We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
// 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 hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
self.ast_region_to_region(lifetime, None).into()
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ fn impl_associated_item_for_impl_trait_in_trait(
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.
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl
// generics.
impl_assoc_ty.generics_of({
let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
let trait_assoc_parent_count = trait_assoc_generics.parent_count;
Expand All @@ -391,16 +393,10 @@ fn impl_associated_item_for_impl_trait_in_trait(
let parent_generics = tcx.generics_of(impl_def_id);
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 {
param.index = param.index + parent_count as u32 + impl_fn_params.len() as u32
- trait_assoc_parent_count as u32;
param.index = param.index + 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 =
params.iter().map(|param| (param.def_id, param.index)).collect();

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/async-await/in-trait/issue-102310.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// check-pass
// edition:2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]
Expand Down
Original file line number Diff line number Diff line change
@@ -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
--> $DIR/lifetime-mismatch.rs:3:12
--> $DIR/lifetime-mismatch.rs:5:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
Expand All @@ -8,7 +8,7 @@ LL | #![feature(async_fn_in_trait)]
= 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:12:17
--> $DIR/lifetime-mismatch.rs:14:17
|
LL | async fn foo<'a>(&self);
| ---- lifetimes in impl do not match this method in trait
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 2 additions & 0 deletions tests/ui/async-await/in-trait/lifetime-mismatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// edition:2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![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
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/in-trait/early.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// check-pass
// 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)]
#![allow(incomplete_features)]
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/in-trait/issue-102301.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// check-pass
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/in-trait/opaque-in-impl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// check-pass
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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;
| - expected 1 type parameter
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
3 changes: 3 additions & 0 deletions tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
Original file line number Diff line number Diff line change
@@ -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)]
#![allow(incomplete_features)]

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/in-trait/where-clause.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// check-pass
// edition: 2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(return_position_impl_trait_in_trait)]
#![allow(incomplete_features)]
Expand Down