diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ce0ab8a913b0a..90ed0bc38ee78 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1519,6 +1519,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.into(), TypeAnnotationNeeded::E0282, true, + self.param_env, + None, ) .emit() }); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 640729576fcc6..f6e3a93747ca6 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -437,6 +437,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.into(), TypeAnnotationNeeded::E0282, !raw_ptr_call, + self.param_env, + None, ); if raw_ptr_call { err.span_label(span, "cannot call a method on a raw pointer with an unknown pointee type"); diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 391e640f8bcb9..89f5ebe963b6f 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -782,6 +782,8 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { p.into(), TypeAnnotationNeeded::E0282, false, + self.fcx.param_env, + None, ) .emit() } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 21a74bd4020ac..262550732d9ee 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -497,6 +497,7 @@ symbols! { bitxor, bitxor_assign, black_box, + blanket_into_impl, block, bool, bool_then, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index af3b5e0d5d417..5ffb921339bd0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -27,6 +27,7 @@ use crate::errors::{ SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::InferCtxt; +use crate::traits::{ObligationCause, ObligationCtxt}; pub enum TypeAnnotationNeeded { /// ```compile_fail,E0282 @@ -75,6 +76,14 @@ pub enum UnderspecifiedArgKind { Const { is_parameter: bool }, } +enum InferenceSuggestionFormat { + /// The inference suggestion will the provided as the explicit type of a binding. + BindingType, + /// The inference suggestion will the provided in the same expression where the error occurred, + /// expanding method calls into fully-qualified paths specifying the self-type and trait. + FullyQualifiedMethodCall, +} + impl InferenceDiagnosticsData { fn can_add_more_info(&self) -> bool { !(self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. })) @@ -420,6 +429,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, + param_env: ty::ParamEnv<'tcx>, + originating_projection: Option>, ) -> Diag<'a> { let arg = self.resolve_vars_if_possible(arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); @@ -453,17 +464,56 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut infer_subdiags = Vec::new(); let mut multi_suggestions = Vec::new(); match kind { - 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), - x_kind: arg_data.where_x_is_kind(ty), - prefix_kind: arg_data.kind.clone(), - 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, def_id), - }); + InferSourceKind::LetBinding { + insert_span, + pattern_name, + ty, + def_id, + init_expr_hir_id, + } => { + let mut paths = vec![]; + if let Some(def_id) = def_id + && let Some(hir_id) = init_expr_hir_id + && let expr = self.infcx.tcx.hir().expect_expr(hir_id) + && let hir::ExprKind::MethodCall(_, rcvr, _, _) = expr.kind + && let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id) + { + paths = self.get_fully_qualified_path_suggestions_from_impls( + ty, + def_id, + InferenceSuggestionFormat::BindingType, + param_env, + originating_projection, + ); + } + + if paths.is_empty() { + infer_subdiags.push(SourceKindSubdiag::LetLike { + span: insert_span, + name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new), + x_kind: arg_data.where_x_is_kind(ty), + prefix_kind: arg_data.kind.clone(), + 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, def_id), + }); + } else { + for type_name in paths { + infer_subdiags.push(SourceKindSubdiag::LetLike { + span: insert_span, + name: pattern_name + .map(|name| name.to_string()) + .unwrap_or_else(String::new), + x_kind: arg_data.where_x_is_kind(ty), + prefix_kind: arg_data.kind.clone(), + prefix: arg_data.kind.try_get_prefix().unwrap_or_default(), + arg_name: arg_data.name.clone(), + kind: if pattern_name.is_some() { "with_pattern" } else { "other" }, + type_name, + }); + } + } } InferSourceKind::ClosureArg { insert_span, ty } => { infer_subdiags.push(SourceKindSubdiag::LetLike { @@ -556,12 +606,35 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => "", }; - multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified( - receiver.span, - def_path, - adjustment, - successor, - )); + // Look for all the possible implementations to suggest, otherwise we'll show + // just suggest the syntax for the fully qualified path with placeholders. + let paths = self.get_fully_qualified_path_suggestions_from_impls( + args.type_at(0), + def_id, + InferenceSuggestionFormat::FullyQualifiedMethodCall, + param_env, + originating_projection, + ); + if paths.len() > 20 || paths.is_empty() { + // This will show the fallback impl, so the expression will have type + // parameter placeholders, but it's better than nothing. + multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified( + receiver.span, + def_path, + adjustment, + successor, + )); + } else { + // These are the paths to specific impls. + for path in paths { + multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified( + receiver.span, + path, + adjustment, + successor, + )); + } + } } } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { @@ -653,6 +726,157 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } false } + + /// Given a `self_ty` and a trait item `def_id`, find all relevant `impl`s and provide suitable + /// code for a suggestion. + /// + /// If `suggestion_style` corresponds to a method call expression, then we suggest the + /// fully-qualified path for the associated item. + /// + /// If `suggestion_style` corresponds to a let binding, then we suggest a type suitable for it + /// corresponding to the return type of the associated item. + /// + /// If `originating_projection` corresponds to a math operation, we restrict the suggestions to + /// only `impl`s for the same type that was expected (instead of showing every integer type, + /// mention only the one that is most likely to be relevant). + /// + /// `trait From` is treated specially, in order to look for suitable `Into` `impl`s as well. + fn get_fully_qualified_path_suggestions_from_impls( + &self, + self_ty: Ty<'tcx>, + def_id: DefId, + suggestion_style: InferenceSuggestionFormat, + param_env: ty::ParamEnv<'tcx>, + originating_projection: Option>, + ) -> Vec { + let tcx = self.infcx.tcx; + let mut paths = vec![]; + let name = tcx.item_name(def_id); + let trait_def_id = tcx.parent(def_id); + tcx.for_each_relevant_impl(trait_def_id, self_ty, |impl_def_id| { + let impl_args = self.fresh_args_for_item(DUMMY_SP, impl_def_id); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args); + let impl_self_ty = impl_trait_ref.self_ty(); + if self.probe(|_| { + ObligationCtxt::new(self.infcx) + .eq(&ObligationCause::dummy(), param_env, self_ty, impl_self_ty) + .is_ok() + }) { + // The expr's self type could conform to this impl's self type. + } else { + // Nope, don't bother. + return; + } + + let filter = if let Some(ty::ProjectionPredicate { + projection_term: ty::AliasTerm { def_id, .. }, + term, + }) = originating_projection + && let ty::TermKind::Ty(assoc_ty) = term.unpack() + && tcx.item_name(def_id) == sym::Output + && hir::lang_items::BINARY_OPERATORS + .iter() + .map(|&op| tcx.lang_items().get(op)) + .any(|op| op == Some(tcx.parent(def_id))) + { + // If the predicate that failed to be inferred is an associated type called + // "Output" (from one of the math traits), we will only mention the `Into` and + // `From` impls that correspond to the self type as well, so as to avoid showing + // multiple conversion options. + Some(assoc_ty) + } else { + None + }; + let assocs = tcx.associated_items(impl_def_id); + + if tcx.is_diagnostic_item(sym::blanket_into_impl, impl_def_id) + && let Some(did) = tcx.get_diagnostic_item(sym::From) + { + let mut found = false; + tcx.for_each_impl(did, |impl_def_id| { + // We had an `::into` and we've hit the blanket + // impl for `From`. So we try and look for the right `From` + // impls that *would* apply. We *could* do this in a generalized + // version by evaluating the `where` clauses, but that would be + // way too involved to implement. Instead we special case the + // arguably most common case of `expr.into()`. + let Some(header) = tcx.impl_trait_header(impl_def_id) else { + return; + }; + let target = header.trait_ref.skip_binder().args.type_at(0); + if filter.is_some() && filter != Some(target) { + return; + }; + let target = header.trait_ref.skip_binder().args.type_at(0); + let ty = header.trait_ref.skip_binder().args.type_at(1); + if ty == self_ty { + match suggestion_style { + InferenceSuggestionFormat::BindingType => { + paths.push(if let ty::Infer(_) = target.kind() { + "/* Type */".to_string() + } else { + format!("{target}") + }); + } + InferenceSuggestionFormat::FullyQualifiedMethodCall => { + paths.push(format!("<{self_ty} as Into<{target}>>::into")); + } + } + found = true; + } + }); + if found { + return; + } + } + + // We're at the `impl` level, but we want to get the same method we + // called *on this `impl`*, in order to get the right DefId and args. + let assoc = if let Some(assoc) = assocs.filter_by_name_unhygienic(name).next() { + // Method in the `impl`. + assoc + } else { + let assocs = tcx.associated_items(trait_def_id); + if let Some(assoc) = assocs.filter_by_name_unhygienic(name).next() { + // Method in the `trait`. + assoc + } else { + // The method isn't in this `impl` or `trait`? Not useful to us then. + return; + } + }; + let Some(trait_assoc_item) = assoc.trait_item_def_id else { + return; + }; + let args = impl_trait_ref + .args + .extend_to(tcx, trait_assoc_item, |def, _| self.var_for_def(DUMMY_SP, def)); + match suggestion_style { + InferenceSuggestionFormat::BindingType => { + let fn_sig = tcx.fn_sig(def_id).instantiate(tcx, args); + let ret = fn_sig.skip_binder().output(); + paths.push(if let ty::Infer(_) = ret.kind() { + "/* Type */".to_string() + } else { + format!("{ret}") + }); + } + InferenceSuggestionFormat::FullyQualifiedMethodCall => { + if let Some(did) = tcx.get_diagnostic_item(sym::Into) + && did == trait_def_id + && let Some(arg) = impl_args.types().skip(1).next() + && let ty::Infer(_) | ty::Param(_) = arg.kind() + { + // Skip `>` blanket + } else { + paths.push(self.tcx.value_path_str_with_args(def_id, args)); + } + } + } + }); + paths + } } #[derive(Debug)] @@ -668,6 +892,7 @@ enum InferSourceKind<'tcx> { pattern_name: Option, ty: Ty<'tcx>, def_id: Option, + init_expr_hir_id: Option, }, ClosureArg { insert_span: Span, @@ -853,8 +1078,11 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, '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 + if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, .. }, .. }) + | Some(InferSource { + kind: InferSourceKind::FullyQualifiedMethodCall { def_id: did, .. }, + .. + }) = self.infer_source && let InferSourceKind::LetBinding { ref ty, ref mut def_id, .. } = new_source.kind && ty.is_ty_or_numeric_infer() { @@ -1163,6 +1391,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { pattern_name: local.pat.simple_ident(), ty, def_id: None, + init_expr_hir_id: local.init.map(|e| e.hir_id), }, }) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index fc0de13aeab09..d2a516bf7c31f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -209,6 +209,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_ref.self_ty().skip_binder().into(), TypeAnnotationNeeded::E0282, false, + obligation.param_env, + None, ); return err.stash(span, StashKey::MaybeForgetReturn).unwrap(); } @@ -238,6 +240,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0283, true, + obligation.param_env, + None, ) } else { struct_span_code_err!( @@ -478,6 +482,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0282, false, + obligation.param_env, + None, ) } @@ -497,6 +503,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { a.into(), TypeAnnotationNeeded::E0282, true, + obligation.param_env, + None, ) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { @@ -527,6 +535,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + Some(data), ) .with_note(format!("cannot satisfy `{predicate}`")) } else { @@ -557,6 +567,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + None, ); err } else { @@ -579,6 +591,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ct.into(), TypeAnnotationNeeded::E0284, true, + obligation.param_env, + None, ), ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) if term.is_infer() => diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 432e55e8c9a4c..9e59754227931 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -745,6 +745,7 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_diagnostic_item = "blanket_into_impl"] impl Into for T where U: From, diff --git a/tests/ui/error-codes/E0283.rs b/tests/ui/error-codes/E0283.rs index 5134660e3f4bd..ab5e9094b910f 100644 --- a/tests/ui/error-codes/E0283.rs +++ b/tests/ui/error-codes/E0283.rs @@ -33,5 +33,6 @@ fn main() { fn buzz() { let foo_impl = Impl::new(); let bar = foo_impl.into() * 1u32; //~ ERROR E0283 + // let bar = >::into(foo_impl) * 1u32; foo(bar); } diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr index 381eca5f2a44a..157ba15a3a9ce 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -30,8 +30,8 @@ LL | impl Into for Impl { where U: From; help: try using a fully qualified path to specify the expected types | -LL | let bar = >::into(foo_impl) * 1u32; - | ++++++++++++++++++++++++ ~ +LL | let bar = >::into(foo_impl) * 1u32; + | ++++++++++++++++++++++++++ ~ error: aborting due to 2 previous errors diff --git a/tests/ui/inference/ambiguous_type_parameter.stderr b/tests/ui/inference/ambiguous_type_parameter.stderr index 0674deb63ba0c..e127e0517c0cf 100644 --- a/tests/ui/inference/ambiguous_type_parameter.stderr +++ b/tests/ui/inference/ambiguous_type_parameter.stderr @@ -6,7 +6,7 @@ LL | InMemoryStore.get_raw(&String::default()); | help: try using a fully qualified path to specify the expected types | -LL | >>::get_raw(&InMemoryStore, &String::default()); +LL | >>::get_raw(&InMemoryStore, &String::default()); | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/inference/issue-12028.stderr b/tests/ui/inference/issue-12028.stderr index 3d7fb13d44757..4cf7a0ea5a4fc 100644 --- a/tests/ui/inference/issue-12028.stderr +++ b/tests/ui/inference/issue-12028.stderr @@ -7,7 +7,7 @@ LL | self.input_stream(&mut stream); = note: cannot satisfy `<_ as StreamHasher>::S == ::S` help: try using a fully qualified path to specify the expected types | -LL | >::input_stream(self, &mut stream); +LL | >::input_stream(self, &mut stream); | ++++++++++++++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/inference/issue-70082.stderr b/tests/ui/inference/issue-70082.stderr index 442e7479a9eb4..ab82da917d409 100644 --- a/tests/ui/inference/issue-70082.stderr +++ b/tests/ui/inference/issue-70082.stderr @@ -9,8 +9,8 @@ LL | let y: f64 = 0.01f64 * 1i16.into(); = note: cannot satisfy `>::Output == f64` help: try using a fully qualified path to specify the expected types | -LL | let y: f64 = 0.01f64 * >::into(1i16); - | +++++++++++++++++++++++ ~ +LL | let y: f64 = 0.01f64 * >::into(1i16); + | +++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/inference/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr index 391d3e7613e03..b8be4e9569d85 100644 --- a/tests/ui/inference/issue-71584.stderr +++ b/tests/ui/inference/issue-71584.stderr @@ -9,8 +9,8 @@ LL | d = d % n.into(); = note: cannot satisfy `>::Output == u64` help: try using a fully qualified path to specify the expected types | -LL | d = d % >::into(n); - | +++++++++++++++++++++++ ~ +LL | d = d % >::into(n); + | +++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr index 02c92c1c11d02..68c873520541c 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -13,8 +13,8 @@ LL | if String::from("a") == "a".try_into().unwrap() {} - impl<'a, 'b> PartialEq for String; help: try using a fully qualified path to specify the expected types | -LL | if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} - | +++++++++++++++++++++++++++++++ ~ +LL | if String::from("a") == <_ as TryInto<_>>::try_into("a").unwrap() {} + | ++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72616.rs:22:37 @@ -29,8 +29,8 @@ LL | if String::from("a") == "a".try_into().unwrap() {} = note: required for `&str` to implement `TryInto<_>` help: try using a fully qualified path to specify the expected types | -LL | if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} - | +++++++++++++++++++++++++++++++ ~ +LL | if String::from("a") == <_ as TryInto<_>>::try_into("a").unwrap() {} + | ++++++++++++++++++++++++++++ ~ error: aborting due to 2 previous errors diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 6391672f8617d..6cfe5c44d7df2 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -21,8 +21,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:12:9 @@ -47,8 +59,20 @@ LL | |x| String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | |x| String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | |x| String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | |x| String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | |x| String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | |x| String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed for `&_` --> $DIR/issue-72690.rs:17:9 @@ -89,8 +113,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:28:5 @@ -115,8 +151,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:37:5 @@ -141,8 +189,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:46:5 @@ -167,8 +227,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:53:5 @@ -193,8 +265,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/issue-72690.rs:62:5 @@ -219,8 +303,20 @@ LL | String::from("x".as_ref()); - impl AsRef for str; help: try using a fully qualified path to specify the expected types | -LL | String::from(>::as_ref("x")); - | ++++++++++++++++++++++++++ ~ +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | ++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | String::from(>::as_ref("x")); + | +++++++++++++++++++++++++++++ ~ error: aborting due to 17 previous errors diff --git a/tests/ui/inference/issue-80816.rs b/tests/ui/inference/issue-80816.rs index 4d319b44987e2..dfdea791ebbaa 100644 --- a/tests/ui/inference/issue-80816.rs +++ b/tests/ui/inference/issue-80816.rs @@ -50,6 +50,7 @@ pub fn foo() { let guard: Guard> = s.load(); //~^ ERROR: type annotations needed //~| HELP: try using a fully qualified path to specify the expected types + // let guard: Guard> = >> as Access>>::load(&s); } fn main() {} diff --git a/tests/ui/inference/issue-80816.stderr b/tests/ui/inference/issue-80816.stderr index ab62db8e6af21..6287248c7548f 100644 --- a/tests/ui/inference/issue-80816.stderr +++ b/tests/ui/inference/issue-80816.stderr @@ -21,8 +21,8 @@ LL | impl, P: Deref> Access for P { | unsatisfied trait bound introduced here help: try using a fully qualified path to specify the expected types | -LL | let guard: Guard> = >> as Access>::load(&s); - | ++++++++++++++++++++++++++++++++++++++++++++++++++ ~ +LL | let guard: Guard> = <_ as Access<_>>::load(&s); + | ++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/inference/multiple-impl-apply-2.rs b/tests/ui/inference/multiple-impl-apply-2.rs new file mode 100644 index 0000000000000..5cdd697d4df9f --- /dev/null +++ b/tests/ui/inference/multiple-impl-apply-2.rs @@ -0,0 +1,48 @@ +struct Foo { + inner: u32, +} + +struct Bar { + inner: u32, +} + +#[derive(Clone, Copy)] +struct Baz { + inner: u32, +} + +impl Into for Baz { + fn into (self) -> Bar { + Bar { + inner: self.inner, + } + } +} + +impl From for Foo { + fn from(other: Baz) -> Self { + Self { + inner: other.inner, + } + } +} + +fn main() { + let x: Baz = Baz { inner: 42 }; + + // DOESN'T Compile: Multiple options! + let y = x.into(); //~ ERROR E0283 + + let y_1: Foo = x.into(); + let y_2: Bar = x.into(); + + let z_1 = Foo::from(y_1); + let z_2 = Bar::from(y_2); + + // No type annotations needed, the compiler KNOWS the type must be `Foo`! + let m = magic_foo(x); +} + +fn magic_foo(arg: Baz) -> Foo { + arg.into() +} diff --git a/tests/ui/inference/multiple-impl-apply-2.stderr b/tests/ui/inference/multiple-impl-apply-2.stderr new file mode 100644 index 0000000000000..0bd23a4dec989 --- /dev/null +++ b/tests/ui/inference/multiple-impl-apply-2.stderr @@ -0,0 +1,26 @@ +error[E0283]: type annotations needed + --> $DIR/multiple-impl-apply-2.rs:34:9 + | +LL | let y = x.into(); + | ^ ---- type must be known at this point + | +note: multiple `impl`s satisfying `Baz: Into<_>` found + --> $DIR/multiple-impl-apply-2.rs:14:1 + | +LL | impl Into for Baz { + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: and another `impl` found in the `core` crate: + - impl Into for T + where U: From; +help: consider giving `y` an explicit type + | +LL | let y: Foo = x.into(); + | +++++ +help: consider giving `y` an explicit type + | +LL | let y: Bar = x.into(); + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/inference/multiple-impl-apply.stderr b/tests/ui/inference/multiple-impl-apply.stderr index 1a81955e1e88c..0b043675d855a 100644 --- a/tests/ui/inference/multiple-impl-apply.stderr +++ b/tests/ui/inference/multiple-impl-apply.stderr @@ -15,8 +15,12 @@ LL | impl From for Foo { = note: required for `Baz` to implement `Into<_>` help: consider giving `y` an explicit type | -LL | let y: /* Type */ = x.into(); - | ++++++++++++ +LL | let y: Bar = x.into(); + | +++++ +help: consider giving `y` an explicit type + | +LL | let y: Foo = x.into(); + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-69683.stderr b/tests/ui/issues/issue-69683.stderr index c428ea9ea2c5b..cbc759a467d6e 100644 --- a/tests/ui/issues/issue-69683.stderr +++ b/tests/ui/issues/issue-69683.stderr @@ -7,7 +7,7 @@ LL | 0u16.foo(b); = note: cannot satisfy `>::Array == [u8; 3]` help: try using a fully qualified path to specify the expected types | -LL | >::foo(0u16, b); +LL | >::foo(0u16, b); | +++++++++++++++++++++ ~ error[E0283]: type annotations needed @@ -34,7 +34,7 @@ LL | fn foo(self, x: >::Array); | --- required by a bound in this associated function help: try using a fully qualified path to specify the expected types | -LL | >::foo(0u16, b); +LL | >::foo(0u16, b); | +++++++++++++++++++++ ~ error: aborting due to 2 previous errors diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index b2d2d039ff6a2..0004d53deff8f 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -25,8 +25,12 @@ LL | impl Foo for Vec { | ^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | as Foo>::foo(&x); - | ++++++++++++++++++++++ ~ +LL | as Foo>::foo(&x); + | ++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | as Foo>::foo(&x); + | ++++++++++++++++++++++++++ ~ error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 diff --git a/tests/ui/pattern/slice-pattern-refutable.stderr b/tests/ui/pattern/slice-pattern-refutable.stderr index df5b58d3e9c63..0bb448433d2b1 100644 --- a/tests/ui/pattern/slice-pattern-refutable.stderr +++ b/tests/ui/pattern/slice-pattern-refutable.stderr @@ -8,6 +8,10 @@ help: consider giving this pattern a type | LL | let [a, b, c]: /* Type */ = Zeroes.into() else { | ++++++++++++ +help: consider giving this pattern a type + | +LL | let [a, b, c]: [usize; 3] = Zeroes.into() else { + | ++++++++++++ error[E0282]: type annotations needed --> $DIR/slice-pattern-refutable.rs:21:31 @@ -19,8 +23,8 @@ LL | if let [a, b, c] = Zeroes.into() { | help: try using a fully qualified path to specify the expected types | -LL | if let [a, b, c] = >::into(Zeroes) { - | ++++++++++++++++++++++++++ ~ +LL | if let [a, b, c] = >::into(Zeroes) { + | +++++++++++++++++++++++++++++++++++ ~ error[E0282]: type annotations needed --> $DIR/slice-pattern-refutable.rs:28:31 @@ -32,8 +36,8 @@ LL | if let [a, b, c] = Zeroes.into() { | help: try using a fully qualified path to specify the expected types | -LL | if let [a, b, c] = >::into(Zeroes) { - | ++++++++++++++++++++++++++ ~ +LL | if let [a, b, c] = >::into(Zeroes) { + | +++++++++++++++++++++++++++++++++++ ~ error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/slice-patterns-ambiguity.stderr b/tests/ui/pattern/slice-patterns-ambiguity.stderr index 3ef99d0e2d1bb..c3d4ff2e9a96e 100644 --- a/tests/ui/pattern/slice-patterns-ambiguity.stderr +++ b/tests/ui/pattern/slice-patterns-ambiguity.stderr @@ -19,8 +19,12 @@ LL | if let &[a, b] = Zeroes.into() { | help: try using a fully qualified path to specify the expected types | -LL | if let &[a, b] = >::into(Zeroes) { - | +++++++++++++++++++++++++++ ~ +LL | if let &[a, b] = >::into(Zeroes) { + | ++++++++++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | if let &[a, b] = >::into(Zeroes) { + | +++++++++++++++++++++++++++++++++++++++++ ~ error[E0282]: type annotations needed --> $DIR/slice-patterns-ambiguity.rs:39:29 @@ -32,8 +36,12 @@ LL | if let &[a, b] = Zeroes.into() { | help: try using a fully qualified path to specify the expected types | -LL | if let &[a, b] = >::into(Zeroes) { - | +++++++++++++++++++++++++++ ~ +LL | if let &[a, b] = >::into(Zeroes) { + | ++++++++++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | if let &[a, b] = >::into(Zeroes) { + | +++++++++++++++++++++++++++++++++++++++++ ~ error: aborting due to 3 previous errors diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr index 49230c98a12c1..2cc2158ead51f 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -14,8 +14,8 @@ LL | fn qux(_: impl From) {} | ^^^^^^^^^ required by this bound in `qux` help: try using a fully qualified path to specify the expected types | -LL | qux(>::into(Bar)); - | +++++++++++++++++++++++ ~ +LL | qux(>::into(Bar)); + | +++++++++++++++++++++++++ ~ help: consider removing this method call, as the receiver has type `Bar` and `Bar: From` trivially holds | LL - qux(Bar.into()); diff --git a/tests/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr b/tests/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr index 460595dd961e0..9724871639de9 100644 --- a/tests/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr +++ b/tests/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr @@ -14,8 +14,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | as Method>::method(thing, 42); - | +++++++++++++++++++++++++++++++++++ ~ +LL | as Method>::method(thing, 42); + | ++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | as Method>::method(thing, 42); + | ++++++++++++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 0f4b3c3c877c9..aeefed8521f16 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -52,8 +52,32 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( - impl From for u32; 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(); - | +++++++++++++++++++++++ ~ +LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); + | +++++++++++++++++++++++++ ~ +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(); + | ++++++++++++++++++++++++++ ~ +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(); + | +++++++++++++++++++++++++ ~ +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(); + | ++++++++++++++++++++++++++ ~ +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(); + | +++++++++++++++++++++++++ ~ +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(); + | ++++++++++++++++++++++++++++++ ~ +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(); + | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed for `Box<_>` --> $DIR/issue-77982.rs:37:9 diff --git a/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.rs b/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.rs index e9e2f6b129017..ea56cbd5ab086 100644 --- a/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.rs +++ b/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.rs @@ -19,4 +19,5 @@ where fn main() { let a = A(B); a.method(); //~ ERROR type annotations needed + // as V>::method(a); } diff --git a/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr b/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr index 1d5489845efe6..67b3630bd599c 100644 --- a/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr +++ b/tests/ui/traits/not-suggest-non-existing-fully-qualified-path.stderr @@ -21,7 +21,7 @@ LL | T: I, | ---- unsatisfied trait bound introduced here help: try using a fully qualified path to specify the expected types | -LL | as V>::method(a); +LL | as V<_>>::method(a); | +++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/traits/suggest-fully-qualified-closure.stderr b/tests/ui/traits/suggest-fully-qualified-closure.stderr index a2c1115e673a3..5c9cdff58b342 100644 --- a/tests/ui/traits/suggest-fully-qualified-closure.stderr +++ b/tests/ui/traits/suggest-fully-qualified-closure.stderr @@ -14,8 +14,12 @@ LL | impl MyTrait for Qqq{ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::lol::<_>(&q, ||()); - | +++++++++++++++++++++++++++++++ ~ +LL | >::lol::<_>(&q, ||()); + | +++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::lol::<_>(&q, ||()); + | +++++++++++++++++++++++++++++++++ ~ error: aborting due to 1 previous error diff --git a/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr b/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr index 841acb5ffd3cd..2bf4cedd327d9 100644 --- a/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr +++ b/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr @@ -14,8 +14,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(&thing); - | ++++++++++++++++++++++++++++++ ~ +LL | >::method(&thing); + | ++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(&thing); + | ++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:46:11 @@ -33,8 +37,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(&mut thing); - | +++++++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(&mut thing); + | +++++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(&mut thing); + | +++++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:47:11 @@ -52,8 +60,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(&thing); - | +++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(&thing); + | +++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(&thing); + | +++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:50:14 @@ -71,8 +83,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(&deref_to); - | ++++++++++++++++++++++++++++++ ~ +LL | >::method(&deref_to); + | ++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(&deref_to); + | ++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:51:14 @@ -90,8 +106,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(&mut deref_to); - | +++++++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(&mut deref_to); + | +++++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(&mut deref_to); + | +++++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:52:14 @@ -109,8 +129,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(&deref_to); - | +++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(&deref_to); + | +++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(&deref_to); + | +++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:55:20 @@ -128,8 +152,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(&deref_deref_to); - | ++++++++++++++++++++++++++++++ ~ +LL | >::method(&deref_deref_to); + | ++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(&deref_deref_to); + | ++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:56:20 @@ -147,8 +175,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(&mut deref_deref_to); - | +++++++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(&mut deref_deref_to); + | +++++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(&mut deref_deref_to); + | +++++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-with-adjustment.rs:57:20 @@ -166,8 +198,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(&deref_deref_to); - | +++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(&deref_deref_to); + | +++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(&deref_deref_to); + | +++++++++++++++++++++++++++++++++++++ ~ error: aborting due to 9 previous errors diff --git a/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr b/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr index 1865d81bad19c..40e24383530d5 100644 --- a/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr +++ b/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr @@ -14,8 +14,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(ref_thing); - | +++++++++++++++++++++++++++++ ~ +LL | >::method(ref_thing); + | +++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(ref_thing); + | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:46:15 @@ -33,8 +37,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(ref_thing); - | ++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(ref_thing); + | ++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(ref_thing); + | ++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:49:15 @@ -52,8 +60,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(mut_thing); - | +++++++++++++++++++++++++++++ ~ +LL | >::method(mut_thing); + | +++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(mut_thing); + | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:50:15 @@ -71,8 +83,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(mut_thing); - | +++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(mut_thing); + | +++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(mut_thing); + | +++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:51:15 @@ -90,8 +106,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(mut_thing); - | ++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(mut_thing); + | ++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(mut_thing); + | ++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:54:14 @@ -109,8 +129,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(deref_to); - | +++++++++++++++++++++++++++++ ~ +LL | >::method(deref_to); + | +++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(deref_to); + | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:55:14 @@ -128,8 +152,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(deref_to); - | +++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(deref_to); + | +++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(deref_to); + | +++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:56:14 @@ -147,8 +175,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(deref_to); - | ++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(deref_to); + | ++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(deref_to); + | ++++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:59:20 @@ -166,8 +198,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::method(deref_deref_to); - | +++++++++++++++++++++++++++++ ~ +LL | >::method(deref_deref_to); + | +++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::method(deref_deref_to); + | +++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:60:20 @@ -185,8 +221,12 @@ LL | impl Method for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | >::mut_method(deref_deref_to); - | +++++++++++++++++++++++++++++++++ ~ +LL | >::mut_method(deref_deref_to); + | +++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | >::mut_method(deref_deref_to); + | +++++++++++++++++++++++++++++++++++ ~ error[E0283]: type annotations needed --> $DIR/suggest-fully-qualified-path-without-adjustment.rs:61:20 @@ -204,8 +244,12 @@ LL | impl MethodRef for &Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | -LL | <&Thing as MethodRef>::by_self(deref_deref_to); - | ++++++++++++++++++++++++++++++++++ ~ +LL | <&Thing as MethodRef>::by_self(deref_deref_to); + | ++++++++++++++++++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | <&Thing as MethodRef>::by_self(deref_deref_to); + | ++++++++++++++++++++++++++++++++++++ ~ error: aborting due to 11 previous errors