Skip to content

Commit

Permalink
Check lifetime param count in collect_trait_impl_trait_tys
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 2, 2022
1 parent 56c241c commit bd7ee07
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
39 changes: 18 additions & 21 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ fn compare_predicate_entailment<'tcx>(
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);

let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_m.def_id);
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);

// Check region bounds.
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, &trait_m_generics, &impl_m_generics)?;
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;

// Create obligations for each predicate declared by the impl
// definition in the context of the trait's parameter
Expand Down Expand Up @@ -338,6 +336,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;

let trait_to_impl_substs = impl_trait_ref.substs;

Expand Down Expand Up @@ -722,12 +721,14 @@ fn check_region_bounds_on_impl_item<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
trait_generics: &ty::Generics,
impl_generics: &ty::Generics,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
let trait_params = trait_generics.own_counts().lifetimes;
let impl_generics = tcx.generics_of(impl_m.def_id);
let impl_params = impl_generics.own_counts().lifetimes;

let trait_generics = tcx.generics_of(trait_m.def_id);
let trait_params = trait_generics.own_counts().lifetimes;

debug!(
"check_region_bounds_on_impl_item: \
trait_generics={:?} \
Expand Down Expand Up @@ -761,12 +762,16 @@ fn check_region_bounds_on_impl_item<'tcx>(
None
};

let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind: assoc_item_kind_str(impl_m),
ident: impl_m.ident(tcx),
generics_span,
});
let reported = tcx
.sess
.create_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind: assoc_item_kind_str(impl_m),
ident: impl_m.ident(tcx),
generics_span,
})
.emit_unless(delay);

return Err(reported);
}

Expand Down Expand Up @@ -1504,18 +1509,10 @@ fn compare_type_predicate_entailment<'tcx>(
let trait_to_impl_substs =
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);

let impl_ty_generics = tcx.generics_of(impl_ty.def_id);
let trait_ty_generics = tcx.generics_of(trait_ty.def_id);
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);

check_region_bounds_on_impl_item(
tcx,
impl_ty,
trait_ty,
&trait_ty_generics,
&impl_ty_generics,
)?;
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;

let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);

Expand Down
20 changes: 20 additions & 0 deletions src/test/ui/async-await/in-trait/lifetime-mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// edition:2021

#![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

trait MyTrait {
async fn foo<'a>(&self);
async fn bar(&self);
}

impl MyTrait for i32 {
async fn foo(&self) {}
//~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration

async fn bar(&self) {
self.foo();
}
}

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/async-await/in-trait/lifetime-mismatch.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:3: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:12: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`.

0 comments on commit bd7ee07

Please sign in to comment.