From e8fc076f231699d9a44fc44a1e298ea4f70fdb48 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 28 Sep 2021 14:48:54 +0000 Subject: [PATCH] Consider unfulfilled obligations in binop errors When encountering a binop where the types would have been accepted, if all the predicates had been fulfilled, include information about the predicates and suggest appropriate `#[derive]`s if possible. Point at trait(s) that needs to be `impl`emented. --- compiler/rustc_middle/src/ty/print/pretty.rs | 21 ++ .../src/traits/error_reporting/mod.rs | 2 +- compiler/rustc_typeck/src/check/method/mod.rs | 66 ++++-- .../rustc_typeck/src/check/method/suggest.rs | 121 +++++++++- compiler/rustc_typeck/src/check/op.rs | 68 +++--- .../assignment-operator-unimplemented.stderr | 17 +- src/test/ui/binop/issue-28837.stderr | 213 ++++++++++++++++-- ...-span-PartialEq-enum-struct-variant.stderr | 20 +- .../derives-span-PartialEq-enum.stderr | 20 +- .../derives-span-PartialEq-struct.stderr | 20 +- ...derives-span-PartialEq-tuple-struct.stderr | 20 +- ...eriving-no-inner-impl-error-message.stderr | 20 +- .../note-unsupported.stderr | 17 +- src/test/ui/error-festival.stderr | 17 +- src/test/ui/issues/issue-14091-2.stderr | 17 +- src/test/ui/issues/issue-31076.rs | 2 +- src/test/ui/issues/issue-31076.stderr | 4 +- src/test/ui/issues/issue-3820.stderr | 17 +- src/test/ui/issues/issue-62375.stderr | 10 +- .../ui/methods/method-call-err-msg.stderr | 11 + .../defaulted-never-note.fallback.stderr | 2 +- ...diverging-fallback-no-leak.fallback.stderr | 2 +- .../or-patterns-syntactic-fail.stderr | 17 +- src/test/ui/span/issue-39018.stderr | 17 +- ...pecialization-trait-not-implemented.stderr | 8 + src/test/ui/suggestions/invalid-bin-op.stderr | 9 + .../ui/type/type-ascription-precedence.stderr | 17 +- 27 files changed, 667 insertions(+), 108 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f8a476266d657..c9f0b508f59e0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2171,10 +2171,26 @@ impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> { } } +/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only +/// the trait name. That is, it will print `Trait` instead of +/// `>`. +#[derive(Copy, Clone, TypeFoldable, Lift)] +pub struct TraitRefPrintOnlyTraitName<'tcx>(ty::TraitRef<'tcx>); + +impl fmt::Debug for TraitRefPrintOnlyTraitName<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + impl ty::TraitRef<'tcx> { pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> { TraitRefPrintOnlyTraitPath(self) } + + pub fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> { + TraitRefPrintOnlyTraitName(self) + } } impl ty::Binder<'tcx, ty::TraitRef<'tcx>> { @@ -2193,6 +2209,7 @@ forward_display_to_print! { ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>, ty::Binder<'tcx, ty::TraitRef<'tcx>>, ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + ty::Binder<'tcx, TraitRefPrintOnlyTraitName<'tcx>>, ty::Binder<'tcx, ty::FnSig<'tcx>>, ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>, @@ -2255,6 +2272,10 @@ define_print_and_forward_display! { p!(print_def_path(self.0.def_id, self.0.substs)); } + TraitRefPrintOnlyTraitName<'tcx> { + p!(print_def_path(self.0.def_id, &[])); + } + ty::ParamTy { p!(write("{}", self.name)) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 6447e4cbf2bf6..88e8df81488e6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -521,7 +521,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { "this error might have been caused by changes to \ Rust's type-inference algorithm (see issue #48950 \ \ - for more information).", + for more information)", ); err.help("did you intend to use the type `()` here instead?"); } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 65b3ceb869802..f0f2470e80a8c 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -290,29 +290,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - /// `lookup_method_in_trait` is used for overloaded operators. - /// It does a very narrow slice of what the normal probe/confirm path does. - /// In particular, it doesn't really do any probing: it simply constructs - /// an obligation for a particular trait with the given self type and checks - /// whether that trait is implemented. - // - // FIXME(#18741): it seems likely that we can consolidate some of this - // code with the other method-lookup code. In particular, the second half - // of this method is basically the same as confirmation. - #[instrument(level = "debug", skip(self, span, opt_input_types))] - pub fn lookup_method_in_trait( + pub(super) fn obligation_for_method( &self, span: Span, - m_name: Ident, trait_def_id: DefId, self_ty: Ty<'tcx>, opt_input_types: Option<&[Ty<'tcx>]>, - ) -> Option>> { - debug!( - "lookup_in_trait_adjusted(self_ty={:?}, m_name={}, trait_def_id={:?}, opt_input_types={:?})", - self_ty, m_name, trait_def_id, opt_input_types - ); - + ) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List>) + { // Construct a trait-reference `self_ty : Trait` let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { @@ -332,17 +317,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Construct an obligation let poly_trait_ref = ty::Binder::dummy(trait_ref); - let obligation = traits::Obligation::misc( - span, - self.body_id, - self.param_env, - poly_trait_ref.without_const().to_predicate(self.tcx), + ( + traits::Obligation::misc( + span, + self.body_id, + self.param_env, + poly_trait_ref.without_const().to_predicate(self.tcx), + ), + substs, + ) + } + + /// `lookup_method_in_trait` is used for overloaded operators. + /// It does a very narrow slice of what the normal probe/confirm path does. + /// In particular, it doesn't really do any probing: it simply constructs + /// an obligation for a particular trait with the given self type and checks + /// whether that trait is implemented. + // + // FIXME(#18741): it seems likely that we can consolidate some of this + // code with the other method-lookup code. In particular, the second half + // of this method is basically the same as confirmation. + #[instrument(level = "debug", skip(self, span, opt_input_types))] + pub(super) fn lookup_method_in_trait( + &self, + span: Span, + m_name: Ident, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + opt_input_types: Option<&[Ty<'tcx>]>, + ) -> Option>> { + debug!( + "lookup_in_trait_adjusted(self_ty={:?}, m_name={}, trait_def_id={:?}, opt_input_types={:?})", + self_ty, m_name, trait_def_id, opt_input_types ); + let (obligation, substs) = + self.obligation_for_method(span, trait_def_id, self_ty, opt_input_types); + // Now we want to know if this can be matched if !self.predicate_may_hold(&obligation) { debug!("--> Cannot match obligation"); - return None; // Cannot be matched, no such method resolution is possible. + // Cannot be matched, no such method resolution is possible. + return None; } // Trait must have a method named `m_name` and it should not have @@ -416,7 +432,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx), )); - let callee = MethodCallee { def_id, substs: trait_ref.substs, sig: fn_sig }; + let callee = MethodCallee { def_id, substs, sig: fn_sig }; debug!("callee = {:?}", callee); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index d849e1d5d2828..8c7ec2194644b 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -15,9 +15,9 @@ use rustc_middle::ty::print::with_crate_prefix; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; use rustc_span::lev_distance; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{source_map, FileName, Span}; +use rustc_span::{source_map, FileName, MultiSpan, Span}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::Obligation; +use rustc_trait_selection::traits::{FulfillmentError, Obligation}; use std::cmp::Ordering; use std::iter; @@ -969,6 +969,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } + crate fn note_unmet_impls_on_type( + &self, + err: &mut rustc_errors::DiagnosticBuilder<'_>, + errors: Vec>, + ) { + let all_local_types_needing_impls = + errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(pred) => match pred.self_ty().kind() { + ty::Adt(def, _) => def.did.is_local(), + _ => false, + }, + _ => false, + }); + let mut preds: Vec<_> = errors + .iter() + .filter_map(|e| match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Trait(pred) => Some(pred), + _ => None, + }) + .collect(); + preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty())); + let def_ids = preds + .iter() + .filter_map(|pred| match pred.self_ty().kind() { + ty::Adt(def, _) => Some(def.did), + _ => None, + }) + .collect::>(); + let sm = self.tcx.sess.source_map(); + let mut spans: MultiSpan = def_ids + .iter() + .filter_map(|def_id| { + let span = self.tcx.def_span(*def_id); + if span.is_dummy() { None } else { Some(sm.guess_head_span(span)) } + }) + .collect::>() + .into(); + + for pred in &preds { + match pred.self_ty().kind() { + ty::Adt(def, _) => { + spans.push_span_label( + sm.guess_head_span(self.tcx.def_span(def.did)), + format!("must implement `{}`", pred.trait_ref.print_only_trait_path()), + ); + } + _ => {} + } + } + + if all_local_types_needing_impls && spans.primary_span().is_some() { + let msg = if preds.len() == 1 { + format!( + "an implementation of `{}` might be missing for `{}`", + preds[0].trait_ref.print_only_trait_path(), + preds[0].self_ty() + ) + } else { + format!( + "the following type{} would have to `impl` {} required trait{} for this \ + operation to be valid", + pluralize!(def_ids.len()), + if def_ids.len() == 1 { "its" } else { "their" }, + pluralize!(preds.len()), + ) + }; + err.span_note(spans, &msg); + } + + let preds: Vec<_> = errors.iter().map(|e| (e.obligation.predicate, None)).collect(); + self.suggest_derive(err, &preds); + } + fn suggest_derive( &self, err: &mut DiagnosticBuilder<'_>, @@ -1010,7 +1083,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Some(( format!("{}", trait_ref.self_ty()), self.tcx.def_span(adt_def.did), - format!("{}", trait_ref.print_only_trait_path()), + format!("{}", trait_ref.print_only_trait_name()), )); } None @@ -1033,6 +1106,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { acc }, ); + let mut traits: Vec<_> = unsatisfied_predicates + .iter() + .filter_map(|(pred, _)| { + let trait_pred = + if let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() { + trait_pred + } else { + return None; + }; + if let ty::Adt(adt_def, _) = trait_pred.trait_ref.self_ty().kind() { + if !adt_def.did.is_local() { + return None; + } + } else { + return None; + }; + + let did = trait_pred.def_id(); + let diagnostic_items = self.tcx.diagnostic_items(did.krate); + + if !derivables + .iter() + .any(|trait_derivable| diagnostic_items.get(trait_derivable) == Some(&did)) + { + Some(self.tcx.def_span(did)) + } else { + None + } + }) + .collect(); + traits.sort(); + traits.dedup(); + + let len = traits.len(); + if len > 0 { + let span: MultiSpan = traits.into(); + err.span_note( + span, + &format!("the following trait{} must be implemented", pluralize!(len),), + ); + } + for (self_name, self_span, traits) in &derives_grouped { err.span_suggestion_verbose( self_span.shrink_to_lo(), diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index d0a32420df398..79e004a47db53 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -18,6 +18,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt}; use std::ops::ControlFlow; @@ -257,12 +258,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output() } // error types are considered "builtin" - Err(()) if lhs_ty.references_error() || rhs_ty.references_error() => { - self.tcx.ty_error() - } - Err(()) => { + Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(), + Err(errors) => { let source_map = self.tcx.sess.source_map(); - let (mut err, missing_trait, use_output, involves_fn) = match is_assign { + let (mut err, missing_trait, use_output) = match is_assign { IsAssign::Yes => { let mut err = struct_span_err!( self.tcx.sess, @@ -289,7 +288,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::BinOpKind::Shr => Some("std::ops::ShrAssign"), _ => None, }; - (err, missing_trait, false, false) + self.note_unmet_impls_on_type(&mut err, errors); + (err, missing_trait, false) } IsAssign::No => { let (message, missing_trait, use_output) = match op.node { @@ -376,9 +376,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = struct_span_err!(self.tcx.sess, op.span, E0369, "{}", message.as_str()); - let mut involves_fn = false; if !lhs_expr.span.eq(&rhs_expr.span) { - involves_fn |= self.add_type_neq_err_label( + self.add_type_neq_err_label( &mut err, lhs_expr.span, lhs_ty, @@ -386,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { op, is_assign, ); - involves_fn |= self.add_type_neq_err_label( + self.add_type_neq_err_label( &mut err, rhs_expr.span, rhs_ty, @@ -395,10 +394,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign, ); } - (err, missing_trait, use_output, involves_fn) + self.note_unmet_impls_on_type(&mut err, errors); + (err, missing_trait, use_output) } }; - let mut suggested_deref = false; if let Ref(_, rty, _) = lhs_ty.kind() { if { self.infcx.type_is_copy_modulo_regions(self.param_env, rty, lhs_expr.span) @@ -423,7 +422,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "*".to_string(), rustc_errors::Applicability::MachineApplicable, ); - suggested_deref = true; } } } @@ -474,8 +472,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { bug!("type param visitor stored a non type param: {:?}", ty.kind()); } - } else if !suggested_deref && !involves_fn { - suggest_impl_missing(&mut err, lhs_ty, missing_trait); } } err.emit(); @@ -665,7 +661,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call(ex.hir_id, method); method.sig.output() } - Err(()) => { + Err(errors) => { let actual = self.resolve_vars_if_possible(operand_ty); if !actual.references_error() { let mut err = struct_span_err!( @@ -720,12 +716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Str | Never | Char | Tuple(_) | Array(_, _) => {} Ref(_, lty, _) if *lty.kind() == Str => {} _ => { - let missing_trait = match op { - hir::UnOp::Neg => "std::ops::Neg", - hir::UnOp::Not => "std::ops::Not", - hir::UnOp::Deref => "std::ops::UnDerf", - }; - suggest_impl_missing(&mut err, operand_ty, missing_trait); + self.note_unmet_impls_on_type(&mut err, errors); } } } @@ -741,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs_ty: Ty<'tcx>, other_tys: &[Ty<'tcx>], op: Op, - ) -> Result, ()> { + ) -> Result, Vec>> { let lang = self.tcx.lang_items(); let span = match op { @@ -820,22 +811,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Op::Unary(..) => 0, }, ) { - return Err(()); + return Err(vec![]); } + let opname = Ident::with_dummy_span(opname); let method = trait_did.and_then(|trait_did| { - let opname = Ident::with_dummy_span(opname); self.lookup_method_in_trait(span, opname, trait_did, lhs_ty, Some(other_tys)) }); - match method { - Some(ok) => { + match (method, trait_did) { + (Some(ok), _) => { let method = self.register_infer_ok_obligations(ok); self.select_obligations_where_possible(false, |_| {}); - Ok(method) } - None => Err(()), + (None, None) => Err(vec![]), + (None, Some(trait_did)) => { + let (obligation, _) = + self.obligation_for_method(span, trait_did, lhs_ty, Some(other_tys)); + let mut fulfill = >::new(self.tcx); + fulfill.register_predicate_obligation(self, obligation); + Err(match fulfill.select_where_possible(&self.infcx) { + Err(errors) => errors, + _ => vec![], + }) + } } } } @@ -962,18 +962,6 @@ fn is_builtin_binop<'tcx>(lhs: Ty<'tcx>, rhs: Ty<'tcx>, op: hir::BinOp) -> bool } } -/// If applicable, note that an implementation of `trait` for `ty` may fix the error. -fn suggest_impl_missing(err: &mut DiagnosticBuilder<'_>, ty: Ty<'_>, missing_trait: &str) { - if let Adt(def, _) = ty.peel_refs().kind() { - if def.did.is_local() { - err.note(&format!( - "an implementation of `{}` might be missing for `{}`", - missing_trait, ty - )); - } - } -} - fn suggest_constraining_param( tcx: TyCtxt<'_>, body_id: hir::HirId, diff --git a/src/test/ui/assignment-operator-unimplemented.stderr b/src/test/ui/assignment-operator-unimplemented.stderr index 5304b09de5efe..73c9f86e00220 100644 --- a/src/test/ui/assignment-operator-unimplemented.stderr +++ b/src/test/ui/assignment-operator-unimplemented.stderr @@ -6,7 +6,22 @@ LL | a += *b; | | | cannot use `+=` on type `Foo` | - = note: an implementation of `std::ops::AddAssign` might be missing for `Foo` +note: an implementation of `AddAssign<_>` might be missing for `Foo` + --> $DIR/assignment-operator-unimplemented.rs:1:1 + | +LL | struct Foo; + | ^^^^^^^^^^^ must implement `AddAssign<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait AddAssign { +LL | | /// Performs the `+=` operation. +LL | | /// +LL | | /// # Example +... | +LL | | fn add_assign(&mut self, rhs: Rhs); +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/binop/issue-28837.stderr b/src/test/ui/binop/issue-28837.stderr index 07f67bc3de79d..10f243bab1586 100644 --- a/src/test/ui/binop/issue-28837.stderr +++ b/src/test/ui/binop/issue-28837.stderr @@ -6,7 +6,22 @@ LL | a + a; | | | A | - = note: an implementation of `std::ops::Add` might be missing for `A` +note: an implementation of `Add<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Add<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Add { +LL | | /// The resulting type after applying the `+` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn add(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: cannot subtract `A` from `A` --> $DIR/issue-28837.rs:8:7 @@ -16,7 +31,22 @@ LL | a - a; | | | A | - = note: an implementation of `std::ops::Sub` might be missing for `A` +note: an implementation of `Sub<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Sub<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Sub { +LL | | /// The resulting type after applying the `-` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn sub(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: cannot multiply `A` by `A` --> $DIR/issue-28837.rs:10:7 @@ -26,7 +56,22 @@ LL | a * a; | | | A | - = note: an implementation of `std::ops::Mul` might be missing for `A` +note: an implementation of `Mul<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Mul<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Mul { +LL | | /// The resulting type after applying the `*` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn mul(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: cannot divide `A` by `A` --> $DIR/issue-28837.rs:12:7 @@ -36,7 +81,22 @@ LL | a / a; | | | A | - = note: an implementation of `std::ops::Div` might be missing for `A` +note: an implementation of `Div<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Div<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Div { +LL | | /// The resulting type after applying the `/` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn div(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: cannot mod `A` by `A` --> $DIR/issue-28837.rs:14:7 @@ -46,7 +106,22 @@ LL | a % a; | | | A | - = note: an implementation of `std::ops::Rem` might be missing for `A` +note: an implementation of `Rem<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Rem<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Rem { +LL | | /// The resulting type after applying the `%` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn rem(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: no implementation for `A & A` --> $DIR/issue-28837.rs:16:7 @@ -56,7 +131,22 @@ LL | a & a; | | | A | - = note: an implementation of `std::ops::BitAnd` might be missing for `A` +note: an implementation of `BitAnd<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `BitAnd<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait BitAnd { +LL | | /// The resulting type after applying the `&` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn bitand(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: no implementation for `A | A` --> $DIR/issue-28837.rs:18:7 @@ -66,7 +156,22 @@ LL | a | a; | | | A | - = note: an implementation of `std::ops::BitOr` might be missing for `A` +note: an implementation of `BitOr<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `BitOr<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait BitOr { +LL | | /// The resulting type after applying the `|` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn bitor(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: no implementation for `A << A` --> $DIR/issue-28837.rs:20:7 @@ -76,7 +181,22 @@ LL | a << a; | | | A | - = note: an implementation of `std::ops::Shl` might be missing for `A` +note: an implementation of `Shl<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Shl<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait Shl { +LL | | /// The resulting type after applying the `<<` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn shl(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: no implementation for `A >> A` --> $DIR/issue-28837.rs:22:7 @@ -86,7 +206,22 @@ LL | a >> a; | | | A | - = note: an implementation of `std::ops::Shr` might be missing for `A` +note: an implementation of `Shr<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `Shr<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait Shr { +LL | | /// The resulting type after applying the `>>` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn shr(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: binary operation `==` cannot be applied to type `A` --> $DIR/issue-28837.rs:24:7 @@ -96,7 +231,15 @@ LL | a == a; | | | A | - = note: an implementation of `std::cmp::PartialEq` might be missing for `A` +note: an implementation of `PartialEq<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialEq<_>` +help: consider annotating `A` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `A` --> $DIR/issue-28837.rs:26:7 @@ -106,7 +249,15 @@ LL | a != a; | | | A | - = note: an implementation of `std::cmp::PartialEq` might be missing for `A` +note: an implementation of `PartialEq<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialEq<_>` +help: consider annotating `A` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `<` cannot be applied to type `A` --> $DIR/issue-28837.rs:28:7 @@ -116,7 +267,15 @@ LL | a < a; | | | A | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `A` +note: an implementation of `PartialOrd<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialOrd<_>` +help: consider annotating `A` with `#[derive(PartialOrd)]` + | +LL | #[derive(PartialOrd)] + | error[E0369]: binary operation `<=` cannot be applied to type `A` --> $DIR/issue-28837.rs:30:7 @@ -126,7 +285,15 @@ LL | a <= a; | | | A | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `A` +note: an implementation of `PartialOrd<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialOrd<_>` +help: consider annotating `A` with `#[derive(PartialOrd)]` + | +LL | #[derive(PartialOrd)] + | error[E0369]: binary operation `>` cannot be applied to type `A` --> $DIR/issue-28837.rs:32:7 @@ -136,7 +303,15 @@ LL | a > a; | | | A | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `A` +note: an implementation of `PartialOrd<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialOrd<_>` +help: consider annotating `A` with `#[derive(PartialOrd)]` + | +LL | #[derive(PartialOrd)] + | error[E0369]: binary operation `>=` cannot be applied to type `A` --> $DIR/issue-28837.rs:34:7 @@ -146,7 +321,15 @@ LL | a >= a; | | | A | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `A` +note: an implementation of `PartialOrd<_>` might be missing for `A` + --> $DIR/issue-28837.rs:1:1 + | +LL | struct A; + | ^^^^^^^^^ must implement `PartialOrd<_>` +help: consider annotating `A` with `#[derive(PartialOrd)]` + | +LL | #[derive(PartialOrd)] + | error: aborting due to 15 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr index abcba6da8aaee..19d2425ff23f7 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr @@ -7,8 +7,16 @@ LL | #[derive(PartialEq)] LL | x: Error | ^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6 @@ -19,8 +27,16 @@ LL | #[derive(PartialEq)] LL | x: Error | ^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr index cdb40c39f169c..419832817ca18 100644 --- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr @@ -7,8 +7,16 @@ LL | #[derive(PartialEq)] LL | Error | ^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-enum.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-enum.rs:9:6 @@ -19,8 +27,16 @@ LL | #[derive(PartialEq)] LL | Error | ^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-enum.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr index 4cf8851a098bc..0000f882542ae 100644 --- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr @@ -7,8 +7,16 @@ LL | struct Struct { LL | x: Error | ^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-struct.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-struct.rs:8:5 @@ -19,8 +27,16 @@ LL | struct Struct { LL | x: Error | ^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-struct.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr index 66bc168735389..07fa900a8c829 100644 --- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr @@ -7,8 +7,16 @@ LL | struct Struct( LL | Error | ^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-tuple-struct.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `Error` --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5 @@ -19,8 +27,16 @@ LL | struct Struct( LL | Error | ^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `Error` +note: an implementation of `PartialEq<_>` might be missing for `Error` + --> $DIR/derives-span-PartialEq-tuple-struct.rs:4:1 + | +LL | struct Error; + | ^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `Error` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr index b97f87da4bfce..e322db97fab49 100644 --- a/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr +++ b/src/test/ui/derives/deriving-no-inner-impl-error-message.stderr @@ -7,8 +7,16 @@ LL | struct E { LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` +note: an implementation of `PartialEq<_>` might be missing for `NoCloneOrEq` + --> $DIR/deriving-no-inner-impl-error-message.rs:1:1 + | +LL | struct NoCloneOrEq; + | ^^^^^^^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq` --> $DIR/deriving-no-inner-impl-error-message.rs:5:5 @@ -19,8 +27,16 @@ LL | struct E { LL | x: NoCloneOrEq | ^^^^^^^^^^^^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `NoCloneOrEq` +note: an implementation of `PartialEq<_>` might be missing for `NoCloneOrEq` + --> $DIR/deriving-no-inner-impl-error-message.rs:1:1 + | +LL | struct NoCloneOrEq; + | ^^^^^^^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `NoCloneOrEq` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied --> $DIR/deriving-no-inner-impl-error-message.rs:10:5 diff --git a/src/test/ui/destructuring-assignment/note-unsupported.stderr b/src/test/ui/destructuring-assignment/note-unsupported.stderr index a81324b99e586..7b9788ca0fef3 100644 --- a/src/test/ui/destructuring-assignment/note-unsupported.stderr +++ b/src/test/ui/destructuring-assignment/note-unsupported.stderr @@ -99,7 +99,22 @@ LL | S { x: a, y: b } += s; | | | cannot use `+=` on type `S` | - = note: an implementation of `std::ops::AddAssign` might be missing for `S` +note: an implementation of `AddAssign<_>` might be missing for `S` + --> $DIR/note-unsupported.rs:1:1 + | +LL | struct S { x: u8, y: u8 } + | ^^^^^^^^ must implement `AddAssign<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait AddAssign { +LL | | /// Performs the `+=` operation. +LL | | /// +LL | | /// # Example +... | +LL | | fn add_assign(&mut self, rhs: Rhs); +LL | | } + | |_^ error[E0067]: invalid left-hand side of assignment --> $DIR/note-unsupported.rs:17:22 diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 89a9d965de24a..b8cd7b7464ae3 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -36,7 +36,22 @@ error[E0600]: cannot apply unary operator `!` to type `Question` LL | !Question::Yes; | ^^^^^^^^^^^^^^ cannot apply unary operator `!` | - = note: an implementation of `std::ops::Not` might be missing for `Question` +note: an implementation of `Not` might be missing for `Question` + --> $DIR/error-festival.rs:1:1 + | +LL | enum Question { + | ^^^^^^^^^^^^^ must implement `Not` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait Not { +LL | | /// The resulting type after applying the `!` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn not(self) -> Self::Output; +LL | | } + | |_^ error[E0604]: only `u8` can be cast as `char`, not `u32` --> $DIR/error-festival.rs:25:5 diff --git a/src/test/ui/issues/issue-14091-2.stderr b/src/test/ui/issues/issue-14091-2.stderr index acf837d0f76b8..0b1cc9c768407 100644 --- a/src/test/ui/issues/issue-14091-2.stderr +++ b/src/test/ui/issues/issue-14091-2.stderr @@ -4,7 +4,22 @@ error[E0600]: cannot apply unary operator `!` to type `BytePos` LL | assert!(x, x); | ^^^^^^^^^^^^^^ cannot apply unary operator `!` | - = note: an implementation of `std::ops::Not` might be missing for `BytePos` +note: an implementation of `Not` might be missing for `BytePos` + --> $DIR/issue-14091-2.rs:6:1 + | +LL | pub struct BytePos(pub u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ must implement `Not` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait Not { +LL | | /// The resulting type after applying the `!` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn not(self) -> Self::Output; +LL | | } + | |_^ = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-31076.rs b/src/test/ui/issues/issue-31076.rs index f9c35526ec342..cdb196d4ff23f 100644 --- a/src/test/ui/issues/issue-31076.rs +++ b/src/test/ui/issues/issue-31076.rs @@ -11,7 +11,7 @@ impl Add for i32 {} fn main() { let x = 5 + 6; - //~^ ERROR cannot add `{integer}` to `{integer}` + //~^ ERROR cannot add `i32` to `{integer}` let y = 5i32 + 6i32; //~^ ERROR cannot add `i32` to `i32` } diff --git a/src/test/ui/issues/issue-31076.stderr b/src/test/ui/issues/issue-31076.stderr index 4c0e1cf7ebb0b..ac0d9dc752879 100644 --- a/src/test/ui/issues/issue-31076.stderr +++ b/src/test/ui/issues/issue-31076.stderr @@ -1,8 +1,8 @@ -error[E0369]: cannot add `{integer}` to `{integer}` +error[E0369]: cannot add `i32` to `{integer}` --> $DIR/issue-31076.rs:13:15 | LL | let x = 5 + 6; - | - ^ - {integer} + | - ^ - i32 | | | {integer} diff --git a/src/test/ui/issues/issue-3820.stderr b/src/test/ui/issues/issue-3820.stderr index 84f8f9bd14786..d5c24e1bb6cdb 100644 --- a/src/test/ui/issues/issue-3820.stderr +++ b/src/test/ui/issues/issue-3820.stderr @@ -6,7 +6,22 @@ LL | let w = u * 3; | | | Thing | - = note: an implementation of `std::ops::Mul` might be missing for `Thing` +note: an implementation of `Mul<_>` might be missing for `Thing` + --> $DIR/issue-3820.rs:1:1 + | +LL | struct Thing { + | ^^^^^^^^^^^^ must implement `Mul<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Mul { +LL | | /// The resulting type after applying the `*` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn mul(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-62375.stderr b/src/test/ui/issues/issue-62375.stderr index 6db45630b9437..478e025bed230 100644 --- a/src/test/ui/issues/issue-62375.stderr +++ b/src/test/ui/issues/issue-62375.stderr @@ -6,7 +6,15 @@ LL | a == A::Value; | | | A | - = note: an implementation of `std::cmp::PartialEq` might be missing for `A` +note: an implementation of `PartialEq<_>` might be missing for `A` + --> $DIR/issue-62375.rs:1:1 + | +LL | enum A { + | ^^^^^^ must implement `PartialEq<_>` +help: consider annotating `A` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to previous error diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr index ffeacfe15dd06..c1183e053eb43 100644 --- a/src/test/ui/methods/method-call-err-msg.stderr +++ b/src/test/ui/methods/method-call-err-msg.stderr @@ -55,6 +55,17 @@ LL | .take() = note: the following trait bounds were not satisfied: `Foo: Iterator` which is required by `&mut Foo: Iterator` +note: the following trait must be implemented + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | / pub trait Iterator { +LL | | /// The type of the elements being iterated over. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Item; +... | +LL | | } +LL | | } + | |_^ = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `take`, perhaps you need to implement it: candidate #1: `Iterator` diff --git a/src/test/ui/never_type/defaulted-never-note.fallback.stderr b/src/test/ui/never_type/defaulted-never-note.fallback.stderr index a51edb1f09a94..b105f03f81cdd 100644 --- a/src/test/ui/never_type/defaulted-never-note.fallback.stderr +++ b/src/test/ui/never_type/defaulted-never-note.fallback.stderr @@ -5,7 +5,7 @@ LL | foo(_x); | ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` | = note: this trait is implemented for `()` - = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information). + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: did you intend to use the type `()` here instead? note: required by a bound in `foo` --> $DIR/defaulted-never-note.rs:25:11 diff --git a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr index ce5bbfc249ebc..72cd69380573e 100644 --- a/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/src/test/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -5,7 +5,7 @@ LL | unconstrained_arg(return); | ^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `!` | = note: this trait is implemented for `()` - = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information). + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: did you intend to use the type `()` here instead? note: required by a bound in `unconstrained_arg` --> $DIR/diverging-fallback-no-leak.rs:12:25 diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr index 5406d51c644a5..c94adfe4ab38a 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr +++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr @@ -30,7 +30,22 @@ LL | let _ = |A | B: E| (); | | | E | - = note: an implementation of `std::ops::BitOr` might be missing for `E` +note: an implementation of `BitOr<_>` might be missing for `E` + --> $DIR/or-patterns-syntactic-fail.rs:6:1 + | +LL | enum E { A, B } + | ^^^^^^ must implement `BitOr<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/bit.rs:LL:COL + | +LL | / pub trait BitOr { +LL | | /// The resulting type after applying the `|` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn bitor(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error: aborting due to 5 previous errors diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index c5a0448e798d1..92e86bf5d6c91 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -20,7 +20,22 @@ LL | let y = World::Hello + World::Goodbye; | | | World | - = note: an implementation of `std::ops::Add` might be missing for `World` +note: an implementation of `Add<_>` might be missing for `World` + --> $DIR/issue-39018.rs:15:1 + | +LL | enum World { + | ^^^^^^^^^^ must implement `Add<_>` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Add { +LL | | /// The resulting type after applying the `+` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn add(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ error[E0369]: cannot add `String` to `&str` --> $DIR/issue-39018.rs:11:22 diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index 16ffc661fe0a3..ce981bc00982a 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -22,6 +22,14 @@ LL | println!("{}", MyStruct.foo_one()); | = note: the following trait bounds were not satisfied: `MyStruct: Foo` +note: the following trait must be implemented + --> $DIR/specialization-trait-not-implemented.rs:7:1 + | +LL | / trait Foo { +LL | | fn foo_one(&self) -> &'static str; +LL | | fn foo_two(&self) -> &'static str; +LL | | } + | |_^ = help: items from traits can only be used if the trait is implemented and in scope note: `Foo` defines an item `foo_one`, perhaps you need to implement it --> $DIR/specialization-trait-not-implemented.rs:7:1 diff --git a/src/test/ui/suggestions/invalid-bin-op.stderr b/src/test/ui/suggestions/invalid-bin-op.stderr index 7668eddf6070a..d18c24e53d030 100644 --- a/src/test/ui/suggestions/invalid-bin-op.stderr +++ b/src/test/ui/suggestions/invalid-bin-op.stderr @@ -6,7 +6,16 @@ LL | let _ = s == t; | | | S | +note: an implementation of `PartialEq<_>` might be missing for `S` + --> $DIR/invalid-bin-op.rs:5:1 + | +LL | struct S(T); + | ^^^^^^^^^^^^^^^ must implement `PartialEq<_>` = note: the trait `std::cmp::PartialEq` is not implemented for `S` +help: consider annotating `S` with `#[derive(PartialEq)]` + | +LL | #[derive(PartialEq)] + | error: aborting due to previous error diff --git a/src/test/ui/type/type-ascription-precedence.stderr b/src/test/ui/type/type-ascription-precedence.stderr index 92d3f18e82f44..ebce257b278bb 100644 --- a/src/test/ui/type/type-ascription-precedence.stderr +++ b/src/test/ui/type/type-ascription-precedence.stderr @@ -28,7 +28,22 @@ error[E0600]: cannot apply unary operator `-` to type `Z` LL | -(S: Z); | ^^^^^^^ cannot apply unary operator `-` | - = note: an implementation of `std::ops::Neg` might be missing for `Z` +note: an implementation of `std::ops::Neg` might be missing for `Z` + --> $DIR/type-ascription-precedence.rs:9:1 + | +LL | struct Z; + | ^^^^^^^^^ must implement `std::ops::Neg` +note: the following trait must be implemented + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Neg { +LL | | /// The resulting type after applying the `-` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn neg(self) -> Self::Output; +LL | | } + | |_^ error[E0308]: mismatched types --> $DIR/type-ascription-precedence.rs:45:5