From ef212e7fb306626b4dc2c484aa3cf3b42a83e83a Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 1 Oct 2021 13:05:17 +0000 Subject: [PATCH] Point at overlapping impls when type annotations are needed --- compiler/rustc_middle/src/traits/mod.rs | 12 ++ .../src/traits/error_reporting/mod.rs | 163 ++++++++++++++- .../src/traits/error_reporting/suggestions.rs | 21 +- .../src/traits/select/candidate_assembly.rs | 12 +- .../src/traits/select/mod.rs | 23 +- .../src/traits/specialize/mod.rs | 2 +- compiler/rustc_typeck/src/check/coercion.rs | 5 +- .../coherence-overlap-trait-alias.stderr | 9 +- src/test/ui/error-codes/E0283.stderr | 9 +- src/test/ui/impl-trait/equality.rs | 2 +- src/test/ui/impl-trait/equality.stderr | 19 +- src/test/ui/inference/issue-71732.stderr | 5 +- src/test/ui/inference/issue-72616.stderr | 6 +- src/test/ui/issues/issue-29147.stderr | 8 +- src/test/ui/issues/issue-69455.rs | 1 + src/test/ui/issues/issue-69455.stderr | 24 ++- src/test/ui/issues/issue-69683.rs | 1 + src/test/ui/issues/issue-69683.stderr | 20 +- src/test/ui/issues/issue-72690.rs | 9 + src/test/ui/issues/issue-72690.stderr | 197 ++++++++++++++++-- .../marker_trait_attr/region-overlap.stderr | 16 +- ...method-ambig-one-trait-unknown-int-type.rs | 2 +- ...od-ambig-one-trait-unknown-int-type.stderr | 19 +- src/test/ui/traits/issue-77982.rs | 1 + src/test/ui/traits/issue-77982.stderr | 61 +++++- .../multidispatch-convert-ambig-dest.rs | 3 +- .../multidispatch-convert-ambig-dest.stderr | 31 ++- src/test/ui/traits/test-2.rs | 4 +- src/test/ui/traits/test-2.stderr | 32 ++- 29 files changed, 629 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b089ae22d6d..6570d8e1567 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -440,16 +440,28 @@ pub struct DerivedObligationCause<'tcx> { #[derive(Clone, Debug, TypeFoldable, Lift)] pub enum SelectionError<'tcx> { + /// The trait is not implemented. Unimplemented, + /// After a closure impl has selected, its "outputs" were evaluated + /// (which for closures includes the "input" type params) and they + /// didn't resolve. See `confirm_poly_trait_refs` for more. OutputTypeParameterMismatch( ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>, ty::error::TypeError<'tcx>, ), + /// The trait pointed by `DefId` is not object safe. TraitNotObjectSafe(DefId), + /// A given constant couldn't be evaluated. NotConstEvaluatable(NotConstEvaluatable), + /// Exceeded the recursion depth during type projection. Overflow, + /// Signaling that an error has already been emitted, to avoid + /// multiple errors being shown. ErrorReporting, + /// Multiple applicable `impl`s where found. The `DefId`s correspond to + /// all the `impl`s' Items. + Ambiguous(Vec), } /// When performing resolution, it is typically the case that there 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 225ff5e597e..8396e3263f9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -34,6 +34,7 @@ use std::iter; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::normalize::AtExt as _; +use crate::traits::specialize::to_pretty_impl_header; use on_unimplemented::InferCtxtExt as _; use suggestions::InferCtxtExt as _; @@ -241,6 +242,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut span = obligation.cause.span; let mut err = match *error { + SelectionError::Ambiguous(ref impls) => { + let mut err = self.tcx.sess.struct_span_err( + obligation.cause.span, + &format!("multiple applicable `impl`s for `{}`", obligation.predicate), + ); + self.annotate_source_of_ambiguity(&mut err, impls, obligation.predicate); + err.emit(); + return; + } SelectionError::Unimplemented => { // If this obligation was generated as a result of well-formedness checking, see if we // can get a better error message by performing HIR-based well-formedness checking. @@ -1138,6 +1148,13 @@ trait InferCtxtPrivExt<'tcx> { obligation: &PredicateObligation<'tcx>, ); + fn annotate_source_of_ambiguity( + &self, + err: &mut DiagnosticBuilder<'tcx>, + impls: &[DefId], + predicate: ty::Predicate<'tcx>, + ); + fn maybe_suggest_unsized_generics( &self, err: &mut DiagnosticBuilder<'tcx>, @@ -1549,11 +1566,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ?predicate, ?obligation.cause.code, ); - // Ambiguity errors are often caused as fallout from earlier - // errors. So just ignore them if this infcx is tainted. - if self.is_tainted_by_errors() { - return; - } + // Ambiguity errors are often caused as fallout from earlier errors. + // We ignore them if this `infcx` is tainted in some cases below. let bound_predicate = predicate.kind(); let mut err = match bound_predicate.skip_binder() { @@ -1601,10 +1615,19 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { // check upstream for type errors and don't add the obligations to // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - self.emit_inference_failure_err(body_id, span, subst, vec![], ErrorCode::E0282) + if !self.is_tainted_by_errors() { + self.emit_inference_failure_err( + body_id, + span, + subst, + vec![], + ErrorCode::E0282, + ) .emit(); + } return; } + let impl_candidates = self.find_similar_impl_candidates(trait_ref); let mut err = self.emit_inference_failure_err( body_id, @@ -1613,7 +1636,29 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { impl_candidates, ErrorCode::E0283, ); - err.note(&format!("cannot satisfy `{}`", predicate)); + + let obligation = Obligation::new( + obligation.cause.clone(), + obligation.param_env, + trait_ref.to_poly_trait_predicate(), + ); + let mut selcx = SelectionContext::with_query_mode( + &self, + crate::traits::TraitQueryMode::Standard, + ); + match selcx.select_from_obligation(&obligation) { + Err(SelectionError::Ambiguous(impls)) if impls.len() > 1 => { + self.annotate_source_of_ambiguity(&mut err, &impls, predicate); + } + _ => { + if self.is_tainted_by_errors() { + err.cancel(); + return; + } + err.note(&format!("cannot satisfy `{}`", predicate)); + } + } + if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); } else if let ( @@ -1674,7 +1719,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ty::PredicateKind::WellFormed(arg) => { // Same hacky approach as above to avoid deluging user // with error messages. - if arg.references_error() || self.tcx.sess.has_errors() { + if arg.references_error() + || self.tcx.sess.has_errors() + || self.is_tainted_by_errors() + { return; } @@ -1682,7 +1730,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } ty::PredicateKind::Subtype(data) => { - if data.references_error() || self.tcx.sess.has_errors() { + if data.references_error() + || self.tcx.sess.has_errors() + || self.is_tainted_by_errors() + { // no need to overload user in such cases return; } @@ -1694,7 +1745,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ty::PredicateKind::Projection(data) => { let self_ty = data.projection_ty.self_ty(); let ty = data.ty; - if predicate.references_error() { + if predicate.references_error() || self.is_tainted_by_errors() { return; } if self_ty.needs_infer() && ty.needs_infer() { @@ -1722,7 +1773,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { } _ => { - if self.tcx.sess.has_errors() { + if self.tcx.sess.has_errors() || self.is_tainted_by_errors() { return; } let mut err = struct_span_err!( @@ -1740,6 +1791,96 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { err.emit(); } + fn annotate_source_of_ambiguity( + &self, + err: &mut DiagnosticBuilder<'tcx>, + impls: &[DefId], + predicate: ty::Predicate<'tcx>, + ) { + let mut spans = vec![]; + let mut crates = vec![]; + let mut post = vec![]; + for def_id in impls { + match self.tcx.span_of_impl(*def_id) { + Ok(span) => spans.push(self.tcx.sess.source_map().guess_head_span(span)), + Err(name) => { + crates.push(name); + if let Some(header) = to_pretty_impl_header(self.tcx, *def_id) { + post.push(header); + } + } + } + } + let msg = format!("multiple `impl`s satisfying `{}` found", predicate); + let mut crate_names: Vec<_> = crates.iter().map(|n| format!("`{}`", n)).collect(); + crate_names.sort(); + crate_names.dedup(); + post.sort(); + post.dedup(); + + if self.is_tainted_by_errors() + && crate_names.len() == 1 + && crate_names[0] == "`core`" + && spans.len() == 0 + { + // Avoid complaining about other inference issues for expressions like + // `42 >> 1`, where the types are still `{integer}`, but we want to + // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too? + err.cancel(); + return; + } + let post = if post.len() > 4 { + format!( + ":\n{}\nand {} more", + post.iter().map(|p| format!("- {}", p)).take(4).collect::>().join("\n"), + post.len() - 4, + ) + } else if post.len() > 1 || (post.len() == 1 && post[0].contains("\n")) { + format!(":\n{}", post.iter().map(|p| format!("- {}", p)).collect::>().join("\n"),) + } else if post.len() == 1 { + format!(": `{}`", post[0]) + } else { + String::new() + }; + + match (spans.len(), crates.len(), crate_names.len()) { + (0, 0, 0) => { + err.note(&format!("cannot satisfy `{}`", predicate)); + } + (0, _, 1) => { + err.note(&format!("{} in the `{}` crate{}", msg, crates[0], post,)); + } + (0, _, _) => { + err.note(&format!( + "{} in the following crates: {}{}", + msg, + crate_names.join(", "), + post, + )); + } + (_, 0, 0) => { + let span: MultiSpan = spans.into(); + err.span_note(span, &msg); + } + (_, 1, 1) => { + let span: MultiSpan = spans.into(); + err.span_note(span, &msg); + err.note( + &format!("and another `impl` found in the `{}` crate{}", crates[0], post,), + ); + } + _ => { + let span: MultiSpan = spans.into(); + err.span_note(span, &msg); + err.note(&format!( + "and more `impl`s found in the following crates: {}{}", + crate_names.join(", "), + post, + )); + } + } + } + /// Returns `true` if the trait predicate may apply for *some* assignment /// to the type parameters. fn predicate_can_apply( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 970fb304879..b4fd851f456 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -299,18 +299,15 @@ fn suggest_restriction( generics, trait_ref.without_const().to_predicate(tcx).to_string(), ), - (None, Some((ident, []))) => ( - ident.span.shrink_to_hi(), - format!(": {}", trait_ref.print_only_trait_path().to_string()), - ), - (_, Some((_, [.., bounds]))) => ( - bounds.span().shrink_to_hi(), - format!(" + {}", trait_ref.print_only_trait_path().to_string()), - ), - (Some(_), Some((_, []))) => ( - generics.span.shrink_to_hi(), - format!(": {}", trait_ref.print_only_trait_path().to_string()), - ), + (None, Some((ident, []))) => { + (ident.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path())) + } + (_, Some((_, [.., bounds]))) => { + (bounds.span().shrink_to_hi(), format!(" + {}", trait_ref.print_only_trait_path())) + } + (Some(_), Some((_, []))) => { + (generics.span.shrink_to_hi(), format!(": {}", trait_ref.print_only_trait_path())) + } }; err.span_suggestion_verbose( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index e12b84742bf..1d0c54f86de 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -18,7 +18,7 @@ use crate::traits; use crate::traits::coherence::Conflict; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{util, SelectionResult}; -use crate::traits::{ErrorReporting, Overflow, Unimplemented}; +use crate::traits::{Ambiguous, ErrorReporting, Overflow, Unimplemented}; use super::BuiltinImplConditions; use super::IntercrateAmbiguityCause; @@ -197,7 +197,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // and report ambiguity. if i > 1 { debug!("multiple matches, ambig"); - return Ok(None); + return Err(Ambiguous( + candidates + .into_iter() + .filter_map(|c| match c.candidate { + SelectionCandidate::ImplCandidate(def_id) => Some(def_id), + _ => None, + }) + .collect(), + )); } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 43ffa285b8f..1b26e38fe0e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -357,18 +357,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>> { - debug_assert!(!obligation.predicate.has_escaping_bound_vars()); - - let pec = &ProvisionalEvaluationCache::default(); - let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation); - - let candidate = match self.candidate_from_obligation(&stack) { + let candidate = match self.select_from_obligation(obligation) { Err(SelectionError::Overflow) => { // In standard mode, overflow must have been caught and reported // earlier. assert!(self.query_mode == TraitQueryMode::Canonical); return Err(SelectionError::Overflow); } + Err(SelectionError::Ambiguous(_)) => { + return Ok(None); + } Err(e) => { return Err(e); } @@ -391,6 +389,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + crate fn select_from_obligation( + &mut self, + obligation: &TraitObligation<'tcx>, + ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + debug_assert!(!obligation.predicate.has_escaping_bound_vars()); + + let pec = &ProvisionalEvaluationCache::default(); + let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation); + + self.candidate_from_obligation(&stack) + } + /////////////////////////////////////////////////////////////////////////// // EVALUATION // @@ -915,6 +925,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.candidate_from_obligation(stack) { Ok(Some(c)) => self.evaluate_candidate(stack, &c), + Err(SelectionError::Ambiguous(_)) => Ok(EvaluatedToAmbig), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow) => Err(OverflowError::Canonical), Err(ErrorReporting) => Err(OverflowError::ErrorReporting), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 88aca794a6b..f9867f0671e 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -464,7 +464,7 @@ fn report_conflicting_impls( /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a /// string. -fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { +crate fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { use std::fmt::Write; let trait_ref = tcx.impl_trait_ref(impl_def_id)?; diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 40f456de183..ad65a0ba62a 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -185,9 +185,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug!("coerce: unsize not object safe"); return Err(TypeError::ObjectUnsafeCoercion(did)); } - Err(_) => {} + Err(error) => { + debug!(?error, "coerce: unsize failed"); + } } - debug!("coerce: unsize failed"); // Examine the supertype and consider auto-borrowing. match *b.kind() { diff --git a/src/test/ui/coherence/coherence-overlap-trait-alias.stderr b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr index e2e8ad54beb..affc58b84d4 100644 --- a/src/test/ui/coherence/coherence-overlap-trait-alias.stderr +++ b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr @@ -4,7 +4,14 @@ error[E0283]: type annotations needed LL | impl C for u32 {} | ^ cannot infer type for type `u32` | - = note: cannot satisfy `u32: C` +note: multiple `impl`s satisfying `u32: C` found + --> $DIR/coherence-overlap-trait-alias.rs:13:1 + | +LL | impl C for T {} + | ^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_strict_coherence] +LL | impl C for u32 {} + | ^^^^^^^^^^^^^^ note: required by a bound in `C` --> $DIR/coherence-overlap-trait-alias.rs:11:1 | diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index b6078e30236..95437bf11ad 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -21,7 +21,14 @@ LL | let bar = foo_impl.into() * 1u32; | this method call resolves to `T` | help: use the fully qualified path for the potential candidate: `>::into(foo_impl)` | - = note: cannot satisfy `Impl: Into<_>` +note: multiple `impl`s satisfying `Impl: Into<_>` found + --> $DIR/E0283.rs:17:1 + | +LL | impl Into for Impl { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: and another `impl` found in the `core` crate: + - impl Into for T + where U: From; error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 828b5aac896..9610618ca11 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -17,7 +17,7 @@ fn two(x: bool) -> impl Foo { //~| expected `i32`, found `u32` } -fn sum_to(n: u32) -> impl Foo { +fn sum_to(n: u32) -> impl Foo { //~ ERROR type annotations needed if n == 0 { 0 } else { diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 536a4726c6d..d9819484a96 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -34,7 +34,22 @@ LL | n + sum_to(n - 1) | = help: the trait `Add` is not implemented for `u32` -error: aborting due to 2 previous errors; 1 warning emitted +error[E0283]: type annotations needed + --> $DIR/equality.rs:20:22 + | +LL | fn sum_to(n: u32) -> impl Foo { + | ^^^^^^^^ cannot infer type for type `{integer}` + | + = note: multiple `impl`s satisfying `{integer}: ToString` found in the `alloc` crate: + - impl ToString for i8; + - impl ToString for u8; +note: required because of the requirements on the impl of `Foo` for `{integer}` + --> $DIR/equality.rs:5:26 + | +LL | impl Foo for T {} + | ^^^ ^ -Some errors have detailed explanations: E0277, E0308. +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0277, E0283, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/inference/issue-71732.stderr b/src/test/ui/inference/issue-71732.stderr index 17fad571385..739847c5cd5 100644 --- a/src/test/ui/inference/issue-71732.stderr +++ b/src/test/ui/inference/issue-71732.stderr @@ -6,7 +6,10 @@ LL | .get(&"key".into()) | | | cannot infer type for type parameter `Q` declared on the associated function `get` | - = note: cannot satisfy `String: Borrow<_>` + = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: + - impl Borrow for String; + - impl Borrow for T + where T: ?Sized; error: aborting due to previous error diff --git a/src/test/ui/inference/issue-72616.stderr b/src/test/ui/inference/issue-72616.stderr index 3c9d864c426..0077c734748 100644 --- a/src/test/ui/inference/issue-72616.stderr +++ b/src/test/ui/inference/issue-72616.stderr @@ -6,7 +6,11 @@ LL | if String::from("a") == "a".try_into().unwrap() {} | | | cannot infer type | - = note: cannot satisfy `String: PartialEq<_>` + = note: multiple `impl`s satisfying `String: PartialEq<_>` found in the `alloc` crate: + - impl PartialEq for String; + - impl<'a, 'b> PartialEq<&'a str> for String; + - impl<'a, 'b> PartialEq> for String; + - impl<'a, 'b> PartialEq for String; error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr index f00d5d32bbf..3b011f58b25 100644 --- a/src/test/ui/issues/issue-29147.stderr +++ b/src/test/ui/issues/issue-29147.stderr @@ -4,7 +4,13 @@ error[E0283]: type annotations needed LL | let _ = >::xxx; | ^^^^^^^^^^^^ cannot infer type for struct `S5<_>` | - = note: cannot satisfy `S5<_>: Foo` +note: multiple `impl`s satisfying `S5<_>: Foo` found + --> $DIR/issue-29147.rs:17:1 + | +LL | impl Foo for S5 { fn xxx(&self) {} } + | ^^^^^^^^^^^^^^^^^^^^ +LL | impl Foo for S5 { fn xxx(&self) {} } + | ^^^^^^^^^^^^^^^^^^^^ note: required by `Foo::xxx` --> $DIR/issue-29147.rs:10:13 | diff --git a/src/test/ui/issues/issue-69455.rs b/src/test/ui/issues/issue-69455.rs index f1935ae2534..a53aadcfad0 100644 --- a/src/test/ui/issues/issue-69455.rs +++ b/src/test/ui/issues/issue-69455.rs @@ -27,4 +27,5 @@ impl Test for u64 { fn main() { let xs: Vec = vec![1, 2, 3]; println!("{}", 23u64.test(xs.iter().sum())); //~ ERROR: type annotations needed + //~^ ERROR type annotations needed } diff --git a/src/test/ui/issues/issue-69455.stderr b/src/test/ui/issues/issue-69455.stderr index 430bbcabf83..da84a6b52da 100644 --- a/src/test/ui/issues/issue-69455.stderr +++ b/src/test/ui/issues/issue-69455.stderr @@ -4,6 +4,26 @@ error[E0284]: type annotations needed: cannot satisfy `>::Output LL | println!("{}", 23u64.test(xs.iter().sum())); | ^^^^ cannot satisfy `>::Output == _` -error: aborting due to previous error +error[E0283]: type annotations needed + --> $DIR/issue-69455.rs:29:26 + | +LL | println!("{}", 23u64.test(xs.iter().sum())); + | ^^^^ cannot infer type for type parameter `Rhs` declared on the trait `Test` + | +note: multiple `impl`s satisfying `u64: Test<_>` found + --> $DIR/issue-69455.rs:11:1 + | +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the type argument in the method call + | +LL | println!("{}", 23u64.test(xs.iter().sum::())); + | +++++ -For more information about this error, try `rustc --explain E0284`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0284. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-69683.rs b/src/test/ui/issues/issue-69683.rs index cc7f1fa0f55..7a76e9ef205 100644 --- a/src/test/ui/issues/issue-69683.rs +++ b/src/test/ui/issues/issue-69683.rs @@ -28,5 +28,6 @@ fn main() { let b: [u8; 3] = [0u8; 3]; 0u16.foo(b); //~ ERROR type annotations needed + //~^ ERROR type annotations needed //>::foo(0u16, b); } diff --git a/src/test/ui/issues/issue-69683.stderr b/src/test/ui/issues/issue-69683.stderr index 776370331a4..ecf78e48e0e 100644 --- a/src/test/ui/issues/issue-69683.stderr +++ b/src/test/ui/issues/issue-69683.stderr @@ -4,6 +4,22 @@ error[E0284]: type annotations needed: cannot satisfy `>::Array LL | 0u16.foo(b); | ^^^ cannot satisfy `>::Array == [u8; 3]` -error: aborting due to previous error +error[E0283]: type annotations needed + --> $DIR/issue-69683.rs:30:10 + | +LL | 0u16.foo(b); + | ^^^ cannot infer type for type parameter `I` declared on the trait `Foo` + | +note: multiple `impl`s satisfying `u8: Element<_>` found + --> $DIR/issue-69683.rs:5:1 + | +LL | impl Element<()> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl, S> Element<[S; 3]> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For more information about this error, try `rustc --explain E0284`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0284. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-72690.rs b/src/test/ui/issues/issue-72690.rs index 4edbd9ca15d..916a7832c68 100644 --- a/src/test/ui/issues/issue-72690.rs +++ b/src/test/ui/issues/issue-72690.rs @@ -5,10 +5,13 @@ fn no_err() { fn err() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn local_pat_closure_err() { @@ -17,12 +20,14 @@ fn local_pat_closure_err() { fn err_first_arg_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed |x: String| x; } fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn err_mid_arg_pat() { @@ -31,6 +36,7 @@ fn err_mid_arg_pat() { |x: String| x; |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; @@ -39,12 +45,14 @@ fn err_mid_arg_pat() { fn err_first_local_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed let _ = String::from("x"); } fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn err_mid_local_pat() { @@ -53,6 +61,7 @@ fn err_mid_local_pat() { let _ = String::from("x"); let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr index af3459a7d2d..1747ca5bb04 100644 --- a/src/test/ui/issues/issue-72690.stderr +++ b/src/test/ui/issues/issue-72690.stderr @@ -4,36 +4,89 @@ error[E0283]: type annotations needed LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:7:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + error[E0282]: type annotations needed - --> $DIR/issue-72690.rs:11:6 + --> $DIR/issue-72690.rs:12:6 | LL | |x| String::from("x".as_ref()); | ^ consider giving this closure parameter a type +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:12:9 + | +LL | |x| String::from("x".as_ref()); + | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; +note: required by `from` + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | +LL | fn from(_: T) -> Self; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:12:26 + | +LL | |x| String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + error[E0283]: type annotations needed for `&T` - --> $DIR/issue-72690.rs:15:17 + --> $DIR/issue-72690.rs:18:17 | LL | let _ = "x".as_ref(); | - ^^^^^^ cannot infer type for type parameter `T` declared on the trait `AsRef` | | | consider giving this pattern the explicit type `&T`, where the type parameter `T` is specified | - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:19:5 + --> $DIR/issue-72690.rs:22:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | @@ -41,12 +94,29 @@ LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:25:5 + --> $DIR/issue-72690.rs:22:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:29:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | @@ -54,12 +124,29 @@ LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:33:5 + --> $DIR/issue-72690.rs:29:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:38:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | @@ -67,17 +154,19 @@ LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:41:5 + --> $DIR/issue-72690.rs:38:22 | LL | String::from("x".as_ref()); - | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` | - = note: cannot satisfy `String: From<&_>` -note: required by `from` - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - | -LL | fn from(_: T) -> Self; - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:47:5 @@ -85,7 +174,9 @@ error[E0283]: type annotations needed LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | @@ -93,19 +184,81 @@ LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:55:5 + --> $DIR/issue-72690.rs:47:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:54:5 | LL | String::from("x".as_ref()); | ^^^^^^^^^^^^ cannot infer type for reference `&_` | - = note: cannot satisfy `String: From<&_>` + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:54:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:63:5 + | +LL | String::from("x".as_ref()); + | ^^^^^^^^^^^^ cannot infer type for reference `&_` + | + = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: + - impl<> From<&String> for String; + - impl<> From<&str> for String; +note: required by `from` + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | +LL | fn from(_: T) -> Self; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:63:22 + | +LL | String::from("x".as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; + +error: aborting due to 18 previous errors Some errors have detailed explanations: E0282, E0283. For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/marker_trait_attr/region-overlap.stderr b/src/test/ui/marker_trait_attr/region-overlap.stderr index e4a94d56f12..c1cc6cdaf53 100644 --- a/src/test/ui/marker_trait_attr/region-overlap.stderr +++ b/src/test/ui/marker_trait_attr/region-overlap.stderr @@ -4,7 +4,13 @@ error[E0283]: type annotations needed LL | impl<'a> A for (&'static (), &'a ()) {} | ^ cannot infer type for tuple `(&'static (), &'a ())` | - = note: cannot satisfy `(&'static (), &'a ()): A` +note: multiple `impl`s satisfying `(&'static (), &'a ()): A` found + --> $DIR/region-overlap.rs:5:1 + | +LL | impl<'a> A for (&'static (), &'a ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<'a> A for (&'a (), &'static ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `A` --> $DIR/region-overlap.rs:4:1 | @@ -17,7 +23,13 @@ error[E0283]: type annotations needed LL | impl<'a> A for (&'a (), &'static ()) {} | ^ cannot infer type for tuple `(&'a (), &'static ())` | - = note: cannot satisfy `(&'a (), &'static ()): A` +note: multiple `impl`s satisfying `(&'a (), &'static ()): A` found + --> $DIR/region-overlap.rs:5:1 + | +LL | impl<'a> A for (&'static (), &'a ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<'a> A for (&'a (), &'static ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `A` --> $DIR/region-overlap.rs:4:1 | diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs index 49fe7d1324c..7b2fc34e1af 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -23,7 +23,7 @@ fn m1() { // we couldn't infer the type of the vector just based on calling foo()... let mut x = Vec::new(); //~^ ERROR type annotations needed - x.foo(); + x.foo(); //~ ERROR type annotations needed } fn m2() { diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 4b494c96115..f33672433de 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -6,6 +6,21 @@ LL | let mut x = Vec::new(); | | | consider giving `x` the explicit type `Vec`, where the type parameter `T` is specified +error[E0283]: type annotations needed + --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7 + | +LL | x.foo(); + | ^^^ cannot infer type for struct `Vec<_>` + | +note: multiple `impl`s satisfying `Vec<_>: Foo` found + --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 + | +LL | impl Foo for Vec { + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Foo for Vec { + | ^^^^^^^^^^^^^^^^^^^^^^^ + error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 | @@ -19,7 +34,7 @@ help: you can convert an `isize` to a `usize` and panic if the converted value d LL | let y: usize = x.foo().try_into().unwrap(); | ++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0282, E0308. +Some errors have detailed explanations: E0282, E0283, E0308. For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/traits/issue-77982.rs b/src/test/ui/traits/issue-77982.rs index 03d4fe23cc5..f5be6cf21c1 100644 --- a/src/test/ui/traits/issue-77982.rs +++ b/src/test/ui/traits/issue-77982.rs @@ -6,6 +6,7 @@ fn what() { let opt = String::new(); opts.get(opt.as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn main() { diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 68347207bda..c45bd76524f 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -6,17 +6,50 @@ LL | opts.get(opt.as_ref()); | | | cannot infer type for type parameter `Q` declared on the associated function `get` | - = note: cannot satisfy `String: Borrow<_>` + = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: + - impl Borrow for String; + - impl Borrow for T + where T: ?Sized; error[E0283]: type annotations needed - --> $DIR/issue-77982.rs:12:44 + --> $DIR/issue-77982.rs:8:18 + | +LL | opts.get(opt.as_ref()); + | ----^^^^^^-- + | | | + | | cannot infer type for type parameter `T` declared on the trait `AsRef` + | this method call resolves to `&T` + | + = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: + - impl AsRef for String; + - impl AsRef for String; + - impl AsRef<[u8]> for String; + - impl AsRef for String; +help: use the fully qualified path for the potential candidates + | +LL | opts.get(>::as_ref(opt)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | opts.get(>::as_ref(opt)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | opts.get(>::as_ref(opt)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | opts.get(>::as_ref(opt)); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0283]: type annotations needed + --> $DIR/issue-77982.rs:13:44 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); | ^^^^^^^^^ ----------- this method call resolves to `T` | | | cannot infer type for type parameter `T` declared on the trait `From` | - = note: cannot satisfy `u32: From<_>` + = note: multiple `impl`s satisfying `u32: From<_>` found in the following crates: `core`, `std`: + - impl From for u32; + - impl From for u32; + - impl From for u32; + - impl From for u32; + and 3 more note: required by `from` --> $SRC_DIR/core/src/convert/mod.rs:LL:COL | @@ -24,25 +57,37 @@ LL | fn from(_: T) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed for `Box` - --> $DIR/issue-77982.rs:35:16 + --> $DIR/issue-77982.rs:36:16 | LL | let _ = ().foo(); | - ^^^ cannot infer type for type parameter `T` declared on the trait `Foo` | | | consider giving this pattern the explicit type `Box`, where the type parameter `T` is specified | - = note: cannot satisfy `(): Foo<'_, _>` +note: multiple `impl`s satisfying `(): Foo<'_, _>` found + --> $DIR/issue-77982.rs:29:1 + | +LL | impl Foo<'static, u32> for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<'a> Foo<'a, i16> for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0283]: type annotations needed for `Box` - --> $DIR/issue-77982.rs:39:19 + --> $DIR/issue-77982.rs:40:19 | LL | let _ = (&()).bar(); | - ^^^ cannot infer type for type parameter `T` declared on the trait `Bar` | | | consider giving this pattern the explicit type `Box`, where the type parameter `T` is specified | - = note: cannot satisfy `&(): Bar<'_, _>` +note: multiple `impl`s satisfying `&(): Bar<'_, _>` found + --> $DIR/issue-77982.rs:32:1 + | +LL | impl<'a> Bar<'static, u32> for &'a () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<'a> Bar<'a, i16> for &'a () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.rs b/src/test/ui/traits/multidispatch-convert-ambig-dest.rs index 58cb69a05b7..aa74e11c362 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.rs +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.rs @@ -24,7 +24,8 @@ where T : Convert fn a() { test(22, std::default::Default::default()); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr index 62f5f5aaa88..9fd81b56bf1 100644 --- a/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -4,6 +4,33 @@ error[E0282]: type annotations needed LL | test(22, std::default::Default::default()); | ^^^^ cannot infer type for type parameter `U` declared on the function `test` -error: aborting due to previous error +error[E0283]: type annotations needed + --> $DIR/multidispatch-convert-ambig-dest.rs:26:5 + | +LL | test(22, std::default::Default::default()); + | ^^^^ cannot infer type for type parameter `U` declared on the function `test` + | +note: multiple `impl`s satisfying `i32: Convert<_>` found + --> $DIR/multidispatch-convert-ambig-dest.rs:8:1 + | +LL | impl Convert for i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Convert for i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test` + --> $DIR/multidispatch-convert-ambig-dest.rs:21:11 + | +LL | fn test(_: T, _: U) + | ---- required by a bound in this +LL | where T : Convert + | ^^^^^^^^^^ required by this bound in `test` +help: consider specifying the type arguments in the function call + | +LL | test::(22, std::default::Default::default()); + | ++++++++ -For more information about this error, try `rustc --explain E0282`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/traits/test-2.rs b/src/test/ui/traits/test-2.rs index 342928e882a..d062de25ac8 100644 --- a/src/test/ui/traits/test-2.rs +++ b/src/test/ui/traits/test-2.rs @@ -6,9 +6,9 @@ impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah(&self) {} } impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah(&self) {} } fn main() { - 10.dup::(); + 10.dup::(); //~ ERROR type annotations needed //~^ ERROR this associated function takes 0 generic arguments but 1 - 10.blah::(); + 10.blah::(); //~ ERROR type annotations needed //~^ ERROR this associated function takes 1 generic argument but 2 (Box::new(10) as Box).dup(); //~^ ERROR E0038 diff --git a/src/test/ui/traits/test-2.stderr b/src/test/ui/traits/test-2.stderr index 77ea4e4e974..5eec0124584 100644 --- a/src/test/ui/traits/test-2.stderr +++ b/src/test/ui/traits/test-2.stderr @@ -79,7 +79,35 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box<{integer}>` = note: required by cast to type `Box` -error: aborting due to 5 previous errors +error[E0283]: type annotations needed + --> $DIR/test-2.rs:9:8 + | +LL | 10.dup::(); + | ^^^ cannot infer type for type `{integer}` + | +note: multiple `impl`s satisfying `{integer}: bar` found + --> $DIR/test-2.rs:5:1 + | +LL | impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah(&self) {} } + | ^^^^^^^^^^^^^^^^ +LL | impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah(&self) {} } + | ^^^^^^^^^^^^^^^^ -Some errors have detailed explanations: E0038, E0107. +error[E0283]: type annotations needed + --> $DIR/test-2.rs:11:8 + | +LL | 10.blah::(); + | ^^^^ cannot infer type for type `{integer}` + | +note: multiple `impl`s satisfying `{integer}: bar` found + --> $DIR/test-2.rs:5:1 + | +LL | impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah(&self) {} } + | ^^^^^^^^^^^^^^^^ +LL | impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah(&self) {} } + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0038, E0107, E0283. For more information about an error, try `rustc --explain E0038`.