diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 4f9e069c1763d..a4c36b4c9cd59 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::{self, DefIdTree, InferConst}; use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span}; use std::borrow::Cow; use std::iter; @@ -79,7 +79,7 @@ impl InferenceDiagnosticsData { fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str { if in_type.is_ty_infer() { - "empty" + "" } else if self.name == "_" { // FIXME: Consider specializing this message if there is a single `_` // in the type. @@ -183,13 +183,24 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte printer } -fn ty_to_string<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { +fn ty_to_string<'tcx>( + infcx: &InferCtxt<'tcx>, + ty: Ty<'tcx>, + called_method_def_id: Option, +) -> String { let printer = fmt_printer(infcx, Namespace::TypeNS); let ty = infcx.resolve_vars_if_possible(ty); - match ty.kind() { + match (ty.kind(), called_method_def_id) { // We don't want the regular output for `fn`s because it includes its path in // invalid pseudo-syntax, we want the `fn`-pointer output instead. - ty::FnDef(..) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(), + (ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(), + (_, Some(def_id)) + if ty.is_ty_infer() + && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) => + { + "Vec<_>".to_string() + } + _ if ty.is_ty_infer() => "/* Type */".to_string(), // FIXME: The same thing for closures, but this only works when the closure // does not capture anything. // @@ -213,7 +224,7 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { .map(|args| { args.tuple_fields() .iter() - .map(|arg| ty_to_string(infcx, arg)) + .map(|arg| ty_to_string(infcx, arg, None)) .collect::>() .join(", ") }) @@ -221,7 +232,7 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { let ret = if fn_sig.output().skip_binder().is_unit() { String::new() } else { - format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder())) + format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None)) }; format!("fn({}){}", args, ret) } @@ -368,6 +379,7 @@ impl<'tcx> InferCtxt<'tcx> { } impl<'tcx> TypeErrCtxt<'_, 'tcx> { + #[instrument(level = "debug", skip(self, error_code))] pub fn emit_inference_failure_err( &self, body_id: Option, @@ -406,7 +418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut infer_subdiags = Vec::new(); let mut multi_suggestions = Vec::new(); match kind { - InferSourceKind::LetBinding { insert_span, pattern_name, ty } => { + InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => { infer_subdiags.push(SourceKindSubdiag::LetLike { span: insert_span, name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new), @@ -415,7 +427,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), arg_name: arg_data.name, kind: if pattern_name.is_some() { "with_pattern" } else { "other" }, - type_name: ty_to_string(self, ty), + type_name: ty_to_string(self, ty, def_id), }); } InferSourceKind::ClosureArg { insert_span, ty } => { @@ -427,7 +439,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), arg_name: arg_data.name, kind: "closure", - type_name: ty_to_string(self, ty), + type_name: ty_to_string(self, ty, None), }); } InferSourceKind::GenericArg { @@ -456,33 +468,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { parent_name, }); - let args = fmt_printer(self, Namespace::TypeNS) - .comma_sep(generic_args.iter().copied().map(|arg| { - if arg.is_suggestable(self.tcx, true) { - return arg; - } + let args = if self.infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) + == Some(generics_def_id) + { + "Vec<_>".to_string() + } else { + fmt_printer(self, Namespace::TypeNS) + .comma_sep(generic_args.iter().copied().map(|arg| { + if arg.is_suggestable(self.tcx, true) { + return arg; + } - match arg.unpack() { - GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), - GenericArgKind::Type(_) => self - .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }) - .into(), - GenericArgKind::Const(arg) => self - .next_const_var( - arg.ty(), - ConstVariableOrigin { + match arg.unpack() { + GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), + GenericArgKind::Type(_) => self + .next_ty_var(TypeVariableOrigin { span: rustc_span::DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, - ) - .into(), - } - })) - .unwrap() - .into_buffer(); + kind: TypeVariableOriginKind::MiscVariable, + }) + .into(), + GenericArgKind::Const(arg) => self + .next_const_var( + arg.ty(), + ConstVariableOrigin { + span: rustc_span::DUMMY_SP, + kind: ConstVariableOriginKind::MiscVariable, + }, + ) + .into(), + } + })) + .unwrap() + .into_buffer() + }; if !have_turbofish { infer_subdiags.push(SourceKindSubdiag::GenericSuggestion { @@ -520,7 +538,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { )); } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { - let ty_info = ty_to_string(self, ty); + let ty_info = ty_to_string(self, ty, None); multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return( ty_info, data, @@ -608,6 +626,7 @@ enum InferSourceKind<'tcx> { insert_span: Span, pattern_name: Option, ty: Ty<'tcx>, + def_id: Option, }, ClosureArg { insert_span: Span, @@ -662,7 +681,7 @@ impl<'tcx> InferSourceKind<'tcx> { if ty.is_closure() { ("closure", closure_as_fn_str(infcx, ty)) } else if !ty.is_ty_infer() { - ("normal", ty_to_string(infcx, ty)) + ("normal", ty_to_string(infcx, ty, None)) } else { ("other", String::new()) } @@ -788,10 +807,18 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { /// Uses `fn source_cost` to determine whether this inference source is preferable to /// previous sources. We generally prefer earlier sources. #[instrument(level = "debug", skip(self))] - fn update_infer_source(&mut self, new_source: InferSource<'tcx>) { + fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) { let cost = self.source_cost(&new_source) + self.attempt; debug!(?cost); self.attempt += 1; + if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source + && let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind + && ty.is_ty_infer() + { + // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of + // `let x: _ = iter.collect();`, as this is a very common case. + *def_id = Some(did); + } if cost < self.infer_source_cost { self.infer_source_cost = cost; self.infer_source = Some(new_source); @@ -1092,6 +1119,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { insert_span: local.pat.span.shrink_to_hi(), pattern_name: local.pat.simple_ident(), ty, + def_id: None, }, }) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 85d416c43f95a..ace095736c92f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -827,6 +827,7 @@ symbols! { item_like_imports, iter, iter_repeat, + iterator_collect_fn, kcfi, keyword, kind, 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 19a1f24817700..c68da3e24a190 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -42,7 +42,7 @@ use rustc_middle::ty::{ }; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::sym; use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; use std::iter; @@ -980,6 +980,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref, obligation.cause.body_id, &mut err, + true, ) { // This is *almost* equivalent to // `obligation.cause.code().peel_derives()`, but it gives us the @@ -1015,6 +1016,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref, obligation.cause.body_id, &mut err, + true, ); } } @@ -1434,6 +1436,7 @@ trait InferCtxtPrivExt<'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, body_id: hir::HirId, err: &mut Diagnostic, + other: bool, ) -> bool; /// Gets the parent trait chain start @@ -1888,7 +1891,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, body_id: hir::HirId, err: &mut Diagnostic, + other: bool, ) -> bool { + let other = if other { "other " } else { "" }; let report = |mut candidates: Vec>, err: &mut Diagnostic| { candidates.sort(); candidates.dedup(); @@ -1939,7 +1944,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { candidates.dedup(); let end = if candidates.len() <= 9 { candidates.len() } else { 8 }; err.help(&format!( - "the following other types implement trait `{}`:{}{}", + "the following {other}types implement trait `{}`:{}{}", trait_ref.print_only_trait_path(), candidates[..end].join(""), if len > 9 { format!("\nand {} others", len - 8) } else { String::new() } @@ -2180,7 +2185,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer()); // It doesn't make sense to talk about applicable impls if there are more // than a handful of them. - if impls.len() > 1 && impls.len() < 5 && has_non_region_infer { + if impls.len() > 1 && impls.len() < 10 && has_non_region_infer { self.annotate_source_of_ambiguity(&mut err, &impls, predicate); } else { if self.tainted_by_errors().is_some() { @@ -2188,6 +2193,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return; } err.note(&format!("cannot satisfy `{}`", predicate)); + let impl_candidates = self.find_similar_impl_candidates( + predicate.to_opt_poly_trait_pred().unwrap(), + ); + if impl_candidates.len() < 10 { + self.report_similar_impl_candidates( + impl_candidates, + trait_ref, + body_id.map(|id| id.hir_id).unwrap_or(obligation.cause.body_id), + &mut err, + false, + ); + } } } _ => { @@ -2199,60 +2216,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() { - self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span) - && let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..) - = *obligation.cause.code() + if let ObligationCauseCode::ItemObligation(def_id) + | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() { - let generics = self.tcx.generics_of(def_id); - if generics.params.iter().any(|p| p.name != kw::SelfUpper) - && !snippet.ends_with('>') - && !generics.has_impl_trait() - && !self.tcx.is_fn_trait(def_id) - { - // FIXME: To avoid spurious suggestions in functions where type arguments - // where already supplied, we check the snippet to make sure it doesn't - // end with a turbofish. Ideally we would have access to a `PathSegment` - // instead. Otherwise we would produce the following output: - // - // error[E0283]: type annotations needed - // --> $DIR/issue-54954.rs:3:24 - // | - // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - // | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - // | | - // | cannot infer type - // | help: consider specifying the type argument - // | in the function call: - // | `Tt::const_val::<[i8; 123]>::` - // ... - // LL | const fn const_val() -> usize { - // | - required by this bound in `Tt::const_val` - // | - // = note: cannot satisfy `_: Tt` - - // Clear any more general suggestions in favor of our specific one - err.clear_suggestions(); - - err.span_suggestion_verbose( - span.shrink_to_hi(), - &format!( - "consider specifying the type argument{} in the function call", - pluralize!(generics.params.len()), - ), - format!( - "::<{}>", - generics - .params - .iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ") - ), - Applicability::HasPlaceholders, - ); - } + self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); } if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) = diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 83c7e8977e9f3..1cdee992137da 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1829,6 +1829,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] + #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] fn collect>(self) -> B where Self: Sized, diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr index 919550cac3087..c2a509a196344 100644 --- a/src/test/ui/array-slice-vec/infer_array_len.stderr +++ b/src/test/ui/array-slice-vec/infer_array_len.stderr @@ -6,8 +6,8 @@ LL | let [_, _] = a.into(); | help: consider giving this pattern a type | -LL | let [_, _]: _ = a.into(); - | +++ +LL | let [_, _]: /* Type */ = a.into(); + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr index d5432755cfed3..7a04ed7381e66 100644 --- a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr +++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr @@ -6,8 +6,8 @@ LL | with_closure(|x: u32, y| {}); | help: consider giving this closure parameter an explicit type | -LL | with_closure(|x: u32, y: _| {}); - | +++ +LL | with_closure(|x: u32, y: /* Type */| {}); + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr index 4c24a54bbbe01..9ba24c7a88695 100644 --- a/src/test/ui/closures/issue-52437.stderr +++ b/src/test/ui/closures/issue-52437.stderr @@ -12,8 +12,8 @@ LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] | help: consider giving this closure parameter an explicit type | -LL | [(); &(&'static: loop { |x: _| {}; }) as *const _ as usize] - | +++ +LL | [(); &(&'static: loop { |x: /* Type */| {}; }) as *const _ as usize] + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr index 293ca6232b14e..13ea4a295afd7 100644 --- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -5,6 +5,12 @@ LL | let y = Mask::<_, _>::splat(false); | ^ ------------------- type must be known at this point | = note: cannot satisfy `_: MaskElement` + = help: the following types implement trait `MaskElement`: + i16 + i32 + i64 + i8 + isize note: required by a bound in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the type for type parameter `T` is specified diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 4d0d0253f1b6d..e0444042614bb 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -41,6 +41,7 @@ LL | IsLessOrEqual: True, | ^^^^ | = note: cannot satisfy `IsLessOrEqual: True` + = help: the trait `True` is implemented for `IsLessOrEqual` error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 @@ -49,6 +50,7 @@ LL | IsLessOrEqual: True, | ^^^^ | = note: cannot satisfy `IsLessOrEqual: True` + = help: the trait `True` is implemented for `IsLessOrEqual` error: aborting due to 6 previous errors diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr index 362b8554b2fcb..7491fdc8a693e 100644 --- a/src/test/ui/const-generics/issues/issue-83249.stderr +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -6,8 +6,8 @@ LL | let _ = foo([0; 1]); | help: consider giving this pattern a type | -LL | let _: _ = foo([0; 1]); - | +++ +LL | let _: /* Type */ = foo([0; 1]); + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr index d01aa3617c764..892d3a81f27f9 100644 --- a/src/test/ui/error-codes/E0282.stderr +++ b/src/test/ui/error-codes/E0282.stderr @@ -6,8 +6,8 @@ LL | let x = "hello".chars().rev().collect(); | help: consider giving `x` an explicit type | -LL | let x: _ = "hello".chars().rev().collect(); - | +++ +LL | let x: Vec<_> = "hello".chars().rev().collect(); + | ++++++++ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index 9687eca61fab0..fa4b91cacef72 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -59,7 +59,7 @@ note: required by a bound in `bfnr` | LL | fn bfnr, W: Fn()>(y: T) { | ^^^^ required by this bound in `bfnr` -help: consider specifying the type arguments in the function call +help: consider specifying the generic arguments | LL | bfnr::(x); | +++++++++++ diff --git a/src/test/ui/impl-trait/issues/issue-86719.stderr b/src/test/ui/impl-trait/issues/issue-86719.stderr index 09047cdcbe15c..7592418fdfd62 100644 --- a/src/test/ui/impl-trait/issues/issue-86719.stderr +++ b/src/test/ui/impl-trait/issues/issue-86719.stderr @@ -20,8 +20,8 @@ LL | |_| true | help: consider giving this closure parameter an explicit type | -LL | |_: _| true - | +++ +LL | |_: /* Type */| true + | ++++++++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr index 5c52e7bcfab69..9be1828648011 100644 --- a/src/test/ui/inference/erase-type-params-in-label.stderr +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -10,10 +10,10 @@ note: required by a bound in `foo` | LL | fn foo(t: T, k: K) -> Foo { | ^^^^^^^ required by this bound in `foo` -help: consider specifying the type arguments in the function call +help: consider giving `foo` an explicit type, where the type for type parameter `W` is specified | -LL | let foo = foo::(1, ""); - | ++++++++++++++ +LL | let foo: Foo = foo(1, ""); + | ++++++++++++++++++++++ error[E0283]: type annotations needed for `Bar` --> $DIR/erase-type-params-in-label.rs:5:9 @@ -27,10 +27,10 @@ note: required by a bound in `bar` | LL | fn bar(t: T, k: K) -> Bar { | ^^^^^^^ required by this bound in `bar` -help: consider specifying the type arguments in the function call +help: consider giving `bar` an explicit type, where the type for type parameter `Z` is specified | -LL | let bar = bar::(1, ""); - | +++++++++++ +LL | let bar: Bar = bar(1, ""); + | +++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/issue-72690.stderr b/src/test/ui/inference/issue-72690.stderr index d4eeda07366a8..8eda71ec09bd3 100644 --- a/src/test/ui/inference/issue-72690.stderr +++ b/src/test/ui/inference/issue-72690.stderr @@ -32,8 +32,8 @@ LL | |x| String::from("x".as_ref()); | help: consider giving this closure parameter an explicit type | -LL | |x: _| String::from("x".as_ref()); - | +++ +LL | |x: /* Type */| String::from("x".as_ref()); + | ++++++++++++ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:12:26 diff --git a/src/test/ui/issues/issue-18159.stderr b/src/test/ui/issues/issue-18159.stderr index 605ff3829d19a..5e0589eed435d 100644 --- a/src/test/ui/issues/issue-18159.stderr +++ b/src/test/ui/issues/issue-18159.stderr @@ -6,8 +6,8 @@ LL | let x; | help: consider giving `x` an explicit type | -LL | let x: _; - | +++ +LL | let x: /* Type */; + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-2151.stderr b/src/test/ui/issues/issue-2151.stderr index 31a8ca5fbfac8..c75038b6169c0 100644 --- a/src/test/ui/issues/issue-2151.stderr +++ b/src/test/ui/issues/issue-2151.stderr @@ -8,8 +8,8 @@ LL | x.clone(); | help: consider giving `x` an explicit type | -LL | let x: _ = panic!(); - | +++ +LL | let x: /* Type */ = panic!(); + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-24036.stderr b/src/test/ui/issues/issue-24036.stderr index a42e35c4cad5c..0e73a51faed9a 100644 --- a/src/test/ui/issues/issue-24036.stderr +++ b/src/test/ui/issues/issue-24036.stderr @@ -19,8 +19,8 @@ LL | 1 => |c| c + 1, | help: consider giving this closure parameter an explicit type | -LL | 1 => |c: _| c + 1, - | +++ +LL | 1 => |c: /* Type */| c + 1, + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr index 420104e526d9b..fe2631f947420 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr @@ -6,8 +6,8 @@ LL | |s| s.len() | help: consider giving this closure parameter an explicit type | -LL | |s: _| s.len() - | +++ +LL | |s: /* Type */| s.len() + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/branches3.rs:15:10 @@ -17,8 +17,8 @@ LL | |s| s.len() | help: consider giving this closure parameter an explicit type | -LL | |s: _| s.len() - | +++ +LL | |s: /* Type */| s.len() + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/branches3.rs:23:10 @@ -28,8 +28,8 @@ LL | |s| s.len() | help: consider giving this closure parameter an explicit type | -LL | |s: _| s.len() - | +++ +LL | |s: /* Type */| s.len() + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/branches3.rs:30:10 @@ -39,8 +39,8 @@ LL | |s| s.len() | help: consider giving this closure parameter an explicit type | -LL | |s: _| s.len() - | +++ +LL | |s: /* Type */| s.len() + | ++++++++++++ error: aborting due to 4 previous errors diff --git a/src/test/ui/lifetimes/issue-34979.stderr b/src/test/ui/lifetimes/issue-34979.stderr index 5832c4d173c10..a332c6547b839 100644 --- a/src/test/ui/lifetimes/issue-34979.stderr +++ b/src/test/ui/lifetimes/issue-34979.stderr @@ -5,6 +5,7 @@ LL | &'a (): Foo, | ^^^ | = note: cannot satisfy `&'a (): Foo` + = help: the trait `Foo` is implemented for `&'a T` error: aborting due to previous error diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr index 9eadb88a8ba81..e3b501b2fd558 100644 --- a/src/test/ui/match/match-unresolved-one-arm.stderr +++ b/src/test/ui/match/match-unresolved-one-arm.stderr @@ -6,8 +6,8 @@ LL | let x = match () { | help: consider giving `x` an explicit type | -LL | let x: _ = match () { - | +++ +LL | let x: /* Type */ = match () { + | ++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/pattern/pat-tuple-bad-type.stderr b/src/test/ui/pattern/pat-tuple-bad-type.stderr index 3342b8e4002b9..da369d33397fc 100644 --- a/src/test/ui/pattern/pat-tuple-bad-type.stderr +++ b/src/test/ui/pattern/pat-tuple-bad-type.stderr @@ -9,8 +9,8 @@ LL | (..) => {} | help: consider giving `x` an explicit type | -LL | let x: _; - | +++ +LL | let x: /* Type */; + | ++++++++++++ error[E0308]: mismatched types --> $DIR/pat-tuple-bad-type.rs:10:9 diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr index e6a4e5f19b716..beba7def96f52 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr @@ -193,8 +193,8 @@ LL | let x @ ..; | help: consider giving this pattern a type | -LL | let x @ ..: _; - | +++ +LL | let x @ ..: /* Type */; + | ++++++++++++ error: aborting due to 23 previous errors diff --git a/src/test/ui/resolve/issue-85348.stderr b/src/test/ui/resolve/issue-85348.stderr index f839dd927db99..42b43f825d10c 100644 --- a/src/test/ui/resolve/issue-85348.stderr +++ b/src/test/ui/resolve/issue-85348.stderr @@ -21,8 +21,8 @@ LL | let mut N; | help: consider giving `N` an explicit type | -LL | let mut N: _; - | +++ +LL | let mut N: /* Type */; + | ++++++++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/span/method-and-field-eager-resolution.stderr b/src/test/ui/span/method-and-field-eager-resolution.stderr index 7d240589a3f13..f6efbe40bc234 100644 --- a/src/test/ui/span/method-and-field-eager-resolution.stderr +++ b/src/test/ui/span/method-and-field-eager-resolution.stderr @@ -9,8 +9,8 @@ LL | x.0; | help: consider giving `x` an explicit type | -LL | let mut x: _ = Default::default(); - | +++ +LL | let mut x: /* Type */ = Default::default(); + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/method-and-field-eager-resolution.rs:11:9 @@ -23,8 +23,8 @@ LL | x[0]; | help: consider giving `x` an explicit type | -LL | let mut x: _ = Default::default(); - | +++ +LL | let mut x: /* Type */ = Default::default(); + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 8ab6414d4d8e3..0b57a8212bdc6 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -43,7 +43,15 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | | | required by a bound introduced by this call | - = 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; + - impl From for u32; + - impl From for u32; + - impl From for T; + - impl From for T; help: try using a fully qualified path to specify the expected types | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); diff --git a/src/test/ui/traits/issue-85735.stderr b/src/test/ui/traits/issue-85735.stderr index fa280135beb2d..930708f9ad80c 100644 --- a/src/test/ui/traits/issue-85735.stderr +++ b/src/test/ui/traits/issue-85735.stderr @@ -5,6 +5,9 @@ LL | T: FnMut(&'a ()), | ^^^^^^^^^^^^^ | = note: cannot satisfy `T: FnMut<(&'a (),)>` + = help: the following types implement trait `FnMut`: + &F + &mut F error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr index 48b7946ea820e..9cc15f14a991d 100644 --- a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -6,8 +6,8 @@ LL | |x| x.len() | help: consider giving this closure parameter an explicit type | -LL | |x: _| x.len() - | +++ +LL | |x: /* Type */| x.len() + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:21:10 @@ -17,8 +17,8 @@ LL | |x| x.len() | help: consider giving this closure parameter an explicit type | -LL | |x: _| x.len() - | +++ +LL | |x: /* Type */| x.len() + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr index 4af4c22f75166..87bba3166be6a 100644 --- a/src/test/ui/type/type-annotation-needed.stderr +++ b/src/test/ui/type/type-annotation-needed.stderr @@ -10,7 +10,7 @@ note: required by a bound in `foo` | LL | fn foo>(x: i32) {} | ^^^^^^^^^^^^ required by this bound in `foo` -help: consider specifying the type argument in the function call +help: consider specifying the generic argument | LL | foo::(42); | +++++ diff --git a/src/test/ui/type/type-check/unknown_type_for_closure.stderr b/src/test/ui/type/type-check/unknown_type_for_closure.stderr index 9ae97f390d3e4..e5e29aabf374b 100644 --- a/src/test/ui/type/type-check/unknown_type_for_closure.stderr +++ b/src/test/ui/type/type-check/unknown_type_for_closure.stderr @@ -12,8 +12,8 @@ LL | let x = |_| {}; | help: consider giving this closure parameter an explicit type | -LL | let x = |_: _| {}; - | +++ +LL | let x = |_: /* Type */| {}; + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/unknown_type_for_closure.rs:10:14 diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr index c1ae10efac4b4..1aed1dbe4babd 100644 --- a/src/test/ui/type/type-path-err-node-types.stderr +++ b/src/test/ui/type/type-path-err-node-types.stderr @@ -30,8 +30,8 @@ LL | let _ = |a, b: _| -> _ { 0 }; | help: consider giving this closure parameter an explicit type | -LL | let _ = |a: _, b: _| -> _ { 0 }; - | +++ +LL | let _ = |a: /* Type */, b: _| -> _ { 0 }; + | ++++++++++++ error: aborting due to 5 previous errors