diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index db27e2bd6301b..b41c884528330 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -312,6 +312,14 @@ impl<'hir> Map<'hir> { Some(body_id) } + /// Check if a given `LocalDefId` is in an impl block. + pub fn is_impl_block(self, id: LocalDefId) -> bool { + matches!( + self.get_if_local(id.to_def_id()), + Some(Node::Item(Item { kind: ItemKind::Impl(_), .. })) + ) + } + /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] pub fn body_owned_by(self, id: LocalDefId) -> BodyId { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 4ba2da95fb324..6587eeb879e11 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -150,16 +150,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::print::with_no_trimmed_paths!(ty::print::with_no_visible_paths!({ let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); - // This is also included through the generics list as `Self`, - // but the parser won't allow you to use it - flags.push((sym::_Self, Some(self_ty.to_string()))); - if let Some(def) = self_ty.ty_adt_def() { - // We also want to be able to select self's original - // signature with no type arguments resolved - flags.push(( - sym::_Self, - Some(self.tcx.type_of(def.did()).instantiate_identity().to_string()), - )); + + // Don't add specialized notes on types + if !self.tcx.hir().is_impl_block(obligation.cause.body_id) { + // This is also included through the generics list as `Self`, + // but the parser won't allow you to use it + flags.push((sym::_Self, Some(self_ty.to_string()))); + if let Some(def) = self_ty.ty_adt_def() { + // We also want to be able to select self's original + // signature with no type arguments resolved + flags.push(( + sym::_Self, + Some(self.tcx.type_of(def.did()).instantiate_identity().to_string()), + )); + } } for param in generics.params.iter() { diff --git a/tests/ui/errors/traits/no-specialized-error-for-types-121398.rs b/tests/ui/errors/traits/no-specialized-error-for-types-121398.rs new file mode 100644 index 0000000000000..b3b5cd4a59f0e --- /dev/null +++ b/tests/ui/errors/traits/no-specialized-error-for-types-121398.rs @@ -0,0 +1,12 @@ +trait Bar: Iterator {} + +impl Bar for String {} //~ ERROR `String` is not an iterator [E0277] + +impl Bar for Vec {} //~ ERROR `Vec` is not an iterator [E0277] + +use std::ops::IndexMut; +trait Foo: IndexMut {} + +impl Foo for String {} //~ ERROR the type `String` cannot be mutably indexed by `Idx` [E0277] + +fn main() {} diff --git a/tests/ui/errors/traits/no-specialized-error-for-types-121398.stderr b/tests/ui/errors/traits/no-specialized-error-for-types-121398.stderr new file mode 100644 index 0000000000000..3718bb50ca8a9 --- /dev/null +++ b/tests/ui/errors/traits/no-specialized-error-for-types-121398.stderr @@ -0,0 +1,46 @@ +error[E0277]: `String` is not an iterator + --> $DIR/no-specialized-error-for-types-121398.rs:3:14 + | +LL | impl Bar for String {} + | ^^^^^^ `String` is not an iterator + | + = help: the trait `Iterator` is not implemented for `String` +note: required by a bound in `Bar` + --> $DIR/no-specialized-error-for-types-121398.rs:1:12 + | +LL | trait Bar: Iterator {} + | ^^^^^^^^ required by this bound in `Bar` + +error[E0277]: `Vec` is not an iterator + --> $DIR/no-specialized-error-for-types-121398.rs:5:17 + | +LL | impl Bar for Vec {} + | ^^^^^^ `Vec` is not an iterator + | + = help: the trait `Iterator` is not implemented for `Vec` +note: required by a bound in `Bar` + --> $DIR/no-specialized-error-for-types-121398.rs:1:12 + | +LL | trait Bar: Iterator {} + | ^^^^^^^^ required by this bound in `Bar` + +error[E0277]: the type `String` cannot be mutably indexed by `Idx` + --> $DIR/no-specialized-error-for-types-121398.rs:10:24 + | +LL | impl Foo for String {} + | ^^^^^^ `String` cannot be mutably indexed by `Idx` + | + = help: the trait `IndexMut` is not implemented for `String` +note: required by a bound in `Foo` + --> $DIR/no-specialized-error-for-types-121398.rs:8:17 + | +LL | trait Foo: IndexMut {} + | ^^^^^^^^^^^^^ required by this bound in `Foo` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | impl Foo for String where String: IndexMut {} + | +++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/errors/traits/specialized-error-for-expr.rs b/tests/ui/errors/traits/specialized-error-for-expr.rs new file mode 100644 index 0000000000000..519be964df795 --- /dev/null +++ b/tests/ui/errors/traits/specialized-error-for-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let s = String::from("hello"); + for _ in s {} //~ `String` is not an iterator [E0277] +} diff --git a/tests/ui/errors/traits/specialized-error-for-expr.stderr b/tests/ui/errors/traits/specialized-error-for-expr.stderr new file mode 100644 index 0000000000000..fd1a6d6b6bda8 --- /dev/null +++ b/tests/ui/errors/traits/specialized-error-for-expr.stderr @@ -0,0 +1,12 @@ +error[E0277]: `String` is not an iterator + --> $DIR/specialized-error-for-expr.rs:3:14 + | +LL | for _ in s {} + | ^ `String` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `Iterator` is not implemented for `String`, which is required by `String: IntoIterator` + = note: required for `String` to implement `IntoIterator` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.