diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 6e1060ea05ae9..eef830b1c2176 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -991,6 +991,7 @@ impl SingleAttributeParser for RustcDiagnosticItemParser { Allow(Target::Fn), Allow(Target::Const), Allow(Target::Mod), + Allow(Target::Impl { of_trait: true }), Allow(Target::Impl { of_trait: false }), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: false })), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9530ff4ca9a3d..00b7a5c645625 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1500,6 +1500,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.into(), TypeAnnotationNeeded::E0282, true, + self.param_env, + None, ) .emit() }); @@ -1526,6 +1528,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ct.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 4258896deec70..850d1e29780be 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -516,6 +516,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/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 3229ad161783b..3f5ca6d959a2b 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -191,6 +191,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { infer_var, TypeAnnotationNeeded::E0282, false, + self.param_env, + None, ) .emit() } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index ba5b55b43049f..a97c45528fc3a 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -924,6 +924,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 fb433aef68cf8..162010567d074 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -526,6 +526,7 @@ symbols! { bitxor, bitxor_assign, black_box, + blanket_into_impl, block, blocking, bool, 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 862628ceb422e..49540d4df606d 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 @@ -29,6 +29,7 @@ use crate::errors::{ SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::{InferCtxt, TyOrConstInferVar}; +use crate::traits::{ObligationCause, ObligationCtxt}; pub enum TypeAnnotationNeeded { /// ```compile_fail,E0282 @@ -77,6 +78,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 { .. })) @@ -490,6 +499,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term: Term<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, + param_env: ty::ParamEnv<'tcx>, + originating_projection: Option>, ) -> Diag<'a> { self.emit_inference_failure_err_with_type_hint( body_def_id, @@ -497,6 +508,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term, error_code, should_label_span, + param_env, + originating_projection, None, ) } @@ -508,6 +521,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term: Term<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, + param_env: ty::ParamEnv<'tcx>, + originating_projection: Option>, ty: Option>, ) -> Diag<'a> { let term = self.resolve_vars_if_possible(term); @@ -565,17 +580,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(self.infcx, 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(trait_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, + trait_def_id, + InferenceSuggestionFormat::BindingType, + param_env, + originating_projection, + ); + } + + if !(1..6).contains(&paths.len()) { + 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(self.infcx, 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, trait_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(self.infcx, 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 { @@ -717,12 +771,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 !(1..6).contains(&paths.len()) { + // 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 } => { @@ -773,6 +850,159 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } err } + + /// 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).instantiate(tcx, impl_args).skip_norm_wip(); + 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 = None; + tracing::info!(?originating_projection); + // let filter = if let Some(ty::ProjectionPredicate { + // projection_term: ty::AliasTerm { def_id, .. }, + // term, + // }) = originating_projection + // && let ty::TermKind::Ty(assoc_ty) = term.kind() + // && 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; + for (_ , def_ids) in tcx.trait_impls_of(did).non_blanket_impls().iter() { + for impl_def_id in def_ids { + // 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 header = tcx.impl_trait_header(*impl_def_id); + let target = header.trait_ref.skip_binder().args.type_at(0); + if filter.is_some() && filter != Some(target) { + continue; + }; + 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)] @@ -788,6 +1018,7 @@ enum InferSourceKind<'tcx> { pattern_name: Option, ty: Ty<'tcx>, def_id: Option, + init_expr_hir_id: Option, }, ClosureArg { insert_span: Span, @@ -990,8 +1221,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() { @@ -1335,6 +1569,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { pattern_name: local.pat.simple_ident(), ty, def_id: local.init.and_then(|expr| get_did(self.typeck_results, expr)), + 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 108262d507ef7..7259c7ed92741 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -233,6 +233,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_pred.self_ty().skip_binder().into(), TypeAnnotationNeeded::E0282, false, + obligation.param_env, + None, ) .emit(), Some(e) => e, @@ -287,6 +289,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term, TypeAnnotationNeeded::E0283, true, + obligation.param_env, + None, match &candidates[..] { [candidate] => Some(*candidate), _ => None, @@ -547,6 +551,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term, TypeAnnotationNeeded::E0282, false, + obligation.param_env, + None, ) } @@ -566,6 +572,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { a.into(), TypeAnnotationNeeded::E0282, true, + obligation.param_env, + None, ) } @@ -601,6 +609,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + Some(data), ) .with_note(format!("cannot satisfy `{predicate}`")) .with_long_ty_path(long_ty_path) @@ -633,6 +643,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + None, ) } else { // If we can't find a generic parameter, just print a generic error @@ -655,6 +667,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ct.into(), TypeAnnotationNeeded::E0284, true, + obligation.param_env, + None, ), ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 34cf9c5d0a5b2..84c28be5bed2d 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -764,6 +764,7 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] +#[rustc_diagnostic_item = "blanket_into_impl"] const impl Into for T where U: [const] 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 29baae5f133a2..b680e71e1ad06 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -31,7 +31,7 @@ LL | impl Into for Impl { help: try using a fully qualified path to specify the expected types | LL - let bar = foo_impl.into() * 1u32; -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 835999121d611..2e0831321419a 100644 --- a/tests/ui/inference/ambiguous_type_parameter.stderr +++ b/tests/ui/inference/ambiguous_type_parameter.stderr @@ -7,7 +7,7 @@ LL | InMemoryStore.get_raw(&String::default()); help: try using a fully qualified path to specify the expected types | LL - InMemoryStore.get_raw(&String::default()); -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 0d8ef1c938d4c..1015da37d3858 100644 --- a/tests/ui/inference/issue-12028.stderr +++ b/tests/ui/inference/issue-12028.stderr @@ -8,7 +8,7 @@ LL | self.input_stream(&mut stream); help: try using a fully qualified path to specify the expected types | LL - self.input_stream(&mut stream); -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-72616.stderr b/tests/ui/inference/issue-72616.stderr index 8eba3216a8464..afaaa1a9de1a6 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -16,7 +16,7 @@ LL | if String::from("a") == "a".try_into().unwrap() {} help: try using a fully qualified path to specify the expected types | LL - if String::from("a") == "a".try_into().unwrap() {} -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 1 previous error diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 4926cf9e981ba..caf3bd1cd4a40 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -23,7 +23,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -51,7 +71,27 @@ LL | |x| String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - |x| String::from("x".as_ref()); -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("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); | error[E0283]: type annotations needed for `&_` @@ -68,7 +108,7 @@ LL | let _ = "x".as_ref(); - impl AsRef for str; help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let _: &T = "x".as_ref(); +LL | let _: &_ = "x".as_ref(); | ++++ error[E0283]: type annotations needed @@ -96,7 +136,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -124,7 +184,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -152,7 +232,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -180,7 +280,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -208,7 +328,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -236,7 +376,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +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/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/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index a5f1b76702f57..a1cdebdbe4023 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 @@ -26,7 +26,12 @@ LL | impl Foo for Vec { help: try using a fully qualified path to specify the expected types | LL - x.foo(); -LL + as Foo>::foo(&x); +LL + as Foo>::foo(&x); + | +help: try using a fully qualified path to specify the expected types + | +LL - x.foo(); +LL + as Foo>::foo(&x); | error[E0308]: mismatched types diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr index 3be18fc59e737..0d800dc638fb5 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr @@ -34,7 +34,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -62,7 +82,27 @@ LL | |x| String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - |x| String::from("x".as_ref()); -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("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); | error[E0283]: type annotations needed for `&_` @@ -79,7 +119,7 @@ LL | let _ = "x".as_ref(); - impl AsRef for str; help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let _: &T = "x".as_ref(); +LL | let _: &_ = "x".as_ref(); | ++++ error[E0283]: type annotations needed @@ -107,7 +147,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -135,7 +195,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -163,7 +243,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -191,7 +291,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -219,7 +339,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error[E0283]: type annotations needed @@ -247,7 +387,27 @@ LL | String::from("x".as_ref()); help: try using a fully qualified path to specify the expected types | LL - String::from("x".as_ref()); -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("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); | error: aborting due to 18 previous errors diff --git a/tests/ui/pattern/slice-pattern-refutable.stderr b/tests/ui/pattern/slice-pattern-refutable.stderr index ece5e0283e27e..27f9aae5918f9 100644 --- a/tests/ui/pattern/slice-pattern-refutable.stderr +++ b/tests/ui/pattern/slice-pattern-refutable.stderr @@ -9,7 +9,7 @@ LL | let [a, b, c] = Zeroes.into() else { help: try using a fully qualified path to specify the expected types | LL - let [a, b, c] = Zeroes.into() else { -LL + let [a, b, c] = >::into(Zeroes) else { +LL + let [a, b, c] = >::into(Zeroes) else { | error[E0282]: type annotations needed @@ -23,7 +23,7 @@ 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] = Zeroes.into() { -LL + if let [a, b, c] = >::into(Zeroes) { +LL + if let [a, b, c] = >::into(Zeroes) { | error[E0282]: type annotations needed @@ -37,7 +37,7 @@ 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] = Zeroes.into() { -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 539afed0bc009..2a2426eb8c79a 100644 --- a/tests/ui/pattern/slice-patterns-ambiguity.stderr +++ b/tests/ui/pattern/slice-patterns-ambiguity.stderr @@ -9,7 +9,12 @@ LL | let &[a, b] = Zeroes.into() else { help: try using a fully qualified path to specify the expected types | LL - let &[a, b] = Zeroes.into() else { -LL + let &[a, b] = >::into(Zeroes) else { +LL + let &[a, b] = >::into(Zeroes) else { + | +help: try using a fully qualified path to specify the expected types + | +LL - let &[a, b] = Zeroes.into() else { +LL + let &[a, b] = >::into(Zeroes) else { | error[E0282]: type annotations needed @@ -23,7 +28,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] = Zeroes.into() { -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] = Zeroes.into() { +LL + if let &[a, b] = >::into(Zeroes) { | error[E0282]: type annotations needed @@ -37,7 +47,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] = Zeroes.into() { -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] = Zeroes.into() { +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 870a865f02dd6..21970e13045c4 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -15,7 +15,7 @@ LL | fn qux(_: impl From) {} help: try using a fully qualified path to specify the expected types | LL - qux(Bar.into()); -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 | 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 139488d79f13b..2a5a521018aad 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 @@ -15,7 +15,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - thing.method(42); -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 - thing.method(42); +LL + as Method>::method(thing, 42); | error: aborting due to 1 previous error 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 7a2db203ac3f8..d453f098219b7 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 @@ -22,7 +22,7 @@ LL | T: I, help: try using a fully qualified path to specify the expected types | LL - a.method(); -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 8975d04d5b3ed..e6a7c5709f415 100644 --- a/tests/ui/traits/suggest-fully-qualified-closure.stderr +++ b/tests/ui/traits/suggest-fully-qualified-closure.stderr @@ -15,7 +15,12 @@ LL | impl MyTrait for Qqq{ help: try using a fully qualified path to specify the expected types | LL - q.lol(||()); -LL + >::lol::<_>(&q, ||()); +LL + >::lol::<_>(&q, ||()); + | +help: try using a fully qualified path to specify the expected types + | +LL - q.lol(||()); +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 0996227e69701..875099674613c 100644 --- a/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr +++ b/tests/ui/traits/suggest-fully-qualified-path-with-adjustment.stderr @@ -15,7 +15,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - thing.method(); -LL + >::method(&thing); +LL + >::method(&thing); + | +help: try using a fully qualified path to specify the expected types + | +LL - thing.method(); +LL + >::method(&thing); | error[E0283]: type annotations needed @@ -35,7 +40,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - thing.mut_method(); -LL + >::mut_method(&mut thing); +LL + >::mut_method(&mut thing); + | +help: try using a fully qualified path to specify the expected types + | +LL - thing.mut_method(); +LL + >::mut_method(&mut thing); | error[E0283]: type annotations needed @@ -55,7 +65,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - thing.by_self(); -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.by_self(); +LL + <&Thing as MethodRef>::by_self(&thing); | error[E0283]: type annotations needed @@ -75,7 +90,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.method(); -LL + >::method(&deref_to); +LL + >::method(&deref_to); + | +help: try using a fully qualified path to specify the expected types + | +LL - deref_to.method(); +LL + >::method(&deref_to); | error[E0283]: type annotations needed @@ -95,7 +115,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.mut_method(); -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 - deref_to.mut_method(); +LL + >::mut_method(&mut deref_to); | error[E0283]: type annotations needed @@ -115,7 +140,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.by_self(); -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 - deref_to.by_self(); +LL + <&Thing as MethodRef>::by_self(&deref_to); | error[E0283]: type annotations needed @@ -135,7 +165,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.method(); -LL + >::method(&deref_deref_to); +LL + >::method(&deref_deref_to); + | +help: try using a fully qualified path to specify the expected types + | +LL - deref_deref_to.method(); +LL + >::method(&deref_deref_to); | error[E0283]: type annotations needed @@ -155,7 +190,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.mut_method(); -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 - deref_deref_to.mut_method(); +LL + >::mut_method(&mut deref_deref_to); | error[E0283]: type annotations needed @@ -175,7 +215,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.by_self(); -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 - deref_deref_to.by_self(); +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 629904815f312..f06d43d1da376 100644 --- a/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr +++ b/tests/ui/traits/suggest-fully-qualified-path-without-adjustment.stderr @@ -15,7 +15,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - ref_thing.method(); -LL + >::method(ref_thing); +LL + >::method(ref_thing); + | +help: try using a fully qualified path to specify the expected types + | +LL - ref_thing.method(); +LL + >::method(ref_thing); | error[E0283]: type annotations needed @@ -35,7 +40,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - ref_thing.by_self(); -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 - ref_thing.by_self(); +LL + <&Thing as MethodRef>::by_self(ref_thing); | error[E0283]: type annotations needed @@ -55,7 +65,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - mut_thing.method(); -LL + >::method(mut_thing); +LL + >::method(mut_thing); + | +help: try using a fully qualified path to specify the expected types + | +LL - mut_thing.method(); +LL + >::method(mut_thing); | error[E0283]: type annotations needed @@ -75,7 +90,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - mut_thing.mut_method(); -LL + >::mut_method(mut_thing); +LL + >::mut_method(mut_thing); + | +help: try using a fully qualified path to specify the expected types + | +LL - mut_thing.mut_method(); +LL + >::mut_method(mut_thing); | error[E0283]: type annotations needed @@ -95,7 +115,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - mut_thing.by_self(); -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 - mut_thing.by_self(); +LL + <&Thing as MethodRef>::by_self(mut_thing); | error[E0283]: type annotations needed @@ -115,7 +140,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.method(); -LL + >::method(deref_to); +LL + >::method(deref_to); + | +help: try using a fully qualified path to specify the expected types + | +LL - deref_to.method(); +LL + >::method(deref_to); | error[E0283]: type annotations needed @@ -135,7 +165,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.mut_method(); -LL + >::mut_method(deref_to); +LL + >::mut_method(deref_to); + | +help: try using a fully qualified path to specify the expected types + | +LL - deref_to.mut_method(); +LL + >::mut_method(deref_to); | error[E0283]: type annotations needed @@ -155,7 +190,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - deref_to.by_self(); -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 - deref_to.by_self(); +LL + <&Thing as MethodRef>::by_self(deref_to); | error[E0283]: type annotations needed @@ -175,7 +215,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.method(); -LL + >::method(deref_deref_to); +LL + >::method(deref_deref_to); + | +help: try using a fully qualified path to specify the expected types + | +LL - deref_deref_to.method(); +LL + >::method(deref_deref_to); | error[E0283]: type annotations needed @@ -195,7 +240,12 @@ LL | impl Method for Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.mut_method(); -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 - deref_deref_to.mut_method(); +LL + >::mut_method(deref_deref_to); | error[E0283]: type annotations needed @@ -215,7 +265,12 @@ LL | impl MethodRef for &Thing { help: try using a fully qualified path to specify the expected types | LL - deref_deref_to.by_self(); -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 - deref_deref_to.by_self(); +LL + <&Thing as MethodRef>::by_self(deref_deref_to); | error: aborting due to 11 previous errors diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr index 5d49d442c55d0..c3ca2b5ab79d0 100644 --- a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr @@ -8,7 +8,7 @@ LL | 0u16.foo(b); help: try using a fully qualified path to specify the expected types | LL - 0u16.foo(b); -LL + >::foo(0u16, b); +LL + >::foo(0u16, b); | error[E0283]: type annotations needed @@ -36,7 +36,7 @@ LL | fn foo(self, x: >::Array); help: try using a fully qualified path to specify the expected types | LL - 0u16.foo(b); -LL + >::foo(0u16, b); +LL + >::foo(0u16, b); | error: aborting due to 2 previous errors