From 0ae0643a5353da7b79e53a11beca93ceeea067d5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 22:04:19 +0000 Subject: [PATCH] Skip reporting item name when checking RPITIT GAT's associated type bounds hold --- .../src/infer/error_reporting/note.rs | 18 +++++++---- .../in-trait/bad-item-bound-within-rpitit.rs | 25 ++++++++++++++++ .../bad-item-bound-within-rpitit.stderr | 30 +++++++++++++++++++ 3 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs create mode 100644 tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 7144084c78eb..8cd1b82130b0 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -243,12 +243,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { let mut err = self.report_concrete_failure(*parent, sub, sup); - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{}` from trait", item_name), - ); + + // Don't mention the item name if it's an RPITIT, since that'll just confuse + // folks. + if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { + let trait_item_span = self.tcx.def_span(trait_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label( + trait_item_span, + format!("definition of `{}` from trait", item_name), + ); + } + self.suggest_copy_trait_method_bounds( trait_item_def_id, impl_item_def_id, diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs new file mode 100644 index 000000000000..8b97336fe0c6 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs @@ -0,0 +1,25 @@ +// issue: 114145 + +#![feature(return_position_impl_trait_in_trait)] + +trait Iterable { + type Item<'a> + where + Self: 'a; + + fn iter(&self) -> impl '_ + Iterator>; +} + +impl<'a, I: 'a + Iterable> Iterable for &'a I { + type Item<'b> = I::Item<'a> + where + 'b: 'a; + //~^ ERROR impl has stricter requirements than trait + + fn iter(&self) -> impl 'a + Iterator> { + //~^ ERROR the type `&'a I` does not fulfill the required lifetime + (*self).iter() + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr new file mode 100644 index 000000000000..1e3363268f06 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr @@ -0,0 +1,30 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/bad-item-bound-within-rpitit.rs:16:13 + | +LL | type Item<'a> + | ------------- definition of `Item` from trait +... +LL | 'b: 'a; + | ^^ impl has extra requirement `'b: 'a` + | +help: copy the `where` clause predicates from the trait + | +LL | where Self: 'b; + | ~~~~~~~~~~~~~~ + +error[E0477]: the type `&'a I` does not fulfill the required lifetime + --> $DIR/bad-item-bound-within-rpitit.rs:19:5 + | +LL | fn iter(&self) -> impl 'a + Iterator> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must outlive the anonymous lifetime as defined here + --> $DIR/bad-item-bound-within-rpitit.rs:10:28 + | +LL | fn iter(&self) -> impl '_ + Iterator>; + | ^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0276, E0477. +For more information about an error, try `rustc --explain E0276`.