From bd7ee07d028b47258ba20f496b6a974bd5334355 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 2 Dec 2022 04:00:15 +0000 Subject: [PATCH] Check lifetime param count in collect_trait_impl_trait_tys --- .../src/check/compare_method.rs | 39 +++++++++---------- .../async-await/in-trait/lifetime-mismatch.rs | 20 ++++++++++ .../in-trait/lifetime-mismatch.stderr | 21 ++++++++++ 3 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/async-await/in-trait/lifetime-mismatch.rs create mode 100644 src/test/ui/async-await/in-trait/lifetime-mismatch.stderr diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index ba58672e7595a..82a77416a190c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -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 @@ -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; @@ -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={:?} \ @@ -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); } @@ -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); diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.rs b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs new file mode 100644 index 0000000000000..45ede193c0fc6 --- /dev/null +++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs @@ -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() {} diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr new file mode 100644 index 0000000000000..d87adcc78b6c8 --- /dev/null +++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr @@ -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 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`.