From adc3ea61b9781b6da24c8c91f8ba9b0ba90690fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Aug 2024 15:50:47 +0000 Subject: [PATCH] When annotations needed, look at impls for more accurate suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When encountering an expression that needs type annotations, if we have the trait `DefId` we look for all the `impl`s that could be satisfied by the expression we have (without looking at additional obligations) and suggest the fully qualified to specific impls. For left over type parameters, we replace them with `_`. ``` error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 | LL | let bar = foo_impl.into() * 1u32; | ^^^^ | note: multiple `impl`s satisfying `Impl: Into<_>` found --> $DIR/E0283.rs:17:1 | LL | impl Into for Impl { | ^^^^^^^^^^^^^^^^^^^^^^^ = note: and another `impl` found in the `core` crate: - impl Into for T where U: From; help: try using a fully qualified path to specify the expected types | LL | let bar = <_ as Into<_>>::into(foo_impl) * 1u32; | +++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let bar = >::into(foo_impl) * 1u32; | ++++++++++++++++++++++++++ ~ ``` This approach does not account for blanket-impls, so we can end up with suggestions like `<_ as Into<_>>::into(foo)`. It'd be nice to have a more complete mechanism that does account for all obligations when resolving methods. Do not suggest `path::to::method` In the pretty-printer, we have a weird way to display fully-qualified for non-local impls, where we show a regular path, but the section corresponding to the `` we use non-syntax for it like `path::to`. It should be ``, but this is only better when we are printing code to be suggested, not to find where the `impl` actually is, so we add a new flag to the printer for this. Special case `Into` suggestion to look for `From` `impl`s When we encounter a blanket `` `impl`, look at the `From` `impl`s so that we can suggest the appropriate `Other`: ``` error[E0284]: type annotations needed --> $DIR/issue-70082.rs:7:33 | LL | let y: f64 = 0.01f64 * 1i16.into(); | - ^^^^ | | | type must be known at this point | = 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); | +++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | +++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | ++++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | +++++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | +++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | +++++++++++++++++++++++++ ~ help: try using a fully qualified path to specify the expected types | LL | let y: f64 = 0.01f64 * >::into(1i16); | +++++++++++++++++++++++++++++++ ~ ``` Suggest an appropriate type for a binding of method chain Do the same we do with fully-qualified type suggestions to the suggestion to specify a binding type: ``` error[E0282]: type annotations needed --> $DIR/slice-pattern-refutable.rs:14:9 | LL | let [a, b, c] = Zeroes.into() else { | ^^^^^^^^^ | help: consider giving this pattern a type | LL | let [a, b, c]: _ = Zeroes.into() else { | +++ help: consider giving this pattern a type | LL | let [a, b, c]: [usize; 3] = Zeroes.into() else { | ++++++++++++ ``` review comments - Pass `ParamEnv` through - Remove now-unnecessary `Formatter` mode - Rework the way we pick up the bounds Add naïve mechanism to filter `Into` suggestions involving math ops ``` error[E0284]: type annotations needed --> $DIR/issue-70082.rs:7:33 | LL | let y: f64 = 0.01f64 * 1i16.into(); | - ^^^^ | | | type must be known at this point | = 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); | +++++++++++++++++++++++++ ~ ``` Note that we only suggest `Into`, and not `Into`, `Into`, `Into`, `Into`, `Into` or `Into`. Replace `_` with `/* Type */` in let binding type suggestion Rework the `predicate` "trafficking" to be more targetted Rename `predicate` to `originating_projection`. Pass in only the `ProjectionPredicate` instead of the `Predicate` to avoid needing to destructure as much. --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 + compiler/rustc_hir_typeck/src/method/probe.rs | 2 + compiler/rustc_hir_typeck/src/writeback.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + .../error_reporting/infer/need_type_info.rs | 233 ++++++++++++++++-- .../src/error_reporting/traits/ambiguity.rs | 14 ++ library/core/src/convert/mod.rs | 1 + tests/ui/error-codes/E0283.rs | 1 + tests/ui/error-codes/E0283.stderr | 8 +- .../inference/ambiguous_type_parameter.stderr | 2 +- tests/ui/inference/issue-12028.stderr | 2 +- tests/ui/inference/issue-70082.stderr | 4 +- tests/ui/inference/issue-71584.stderr | 4 +- tests/ui/inference/issue-72616.stderr | 8 +- tests/ui/inference/issue-72690.stderr | 128 ++++++++-- tests/ui/inference/issue-80816.rs | 1 + tests/ui/inference/multiple-impl-apply-2.rs | 48 ++++ .../ui/inference/multiple-impl-apply-2.stderr | 26 ++ tests/ui/inference/multiple-impl-apply.stderr | 8 +- tests/ui/issues/issue-69683.stderr | 4 +- ...od-ambig-one-trait-unknown-int-type.stderr | 8 +- .../ui/pattern/slice-pattern-refutable.stderr | 20 +- .../pattern/slice-patterns-ambiguity.stderr | 24 +- .../types/into-inference-needs-type.stderr | 2 +- ...gument-with-unnecessary-method-call.stderr | 4 +- ...s-by-name-in-suggestion-issue-96292.stderr | 8 +- tests/ui/traits/issue-77982.stderr | 28 ++- ...ggest-non-existing-fully-qualified-path.rs | 1 + ...t-non-existing-fully-qualified-path.stderr | 2 +- .../suggest-fully-qualified-closure.stderr | 8 +- ...ully-qualified-path-with-adjustment.stderr | 72 ++++-- ...y-qualified-path-without-adjustment.stderr | 88 +++++-- 32 files changed, 652 insertions(+), 112 deletions(-) create mode 100644 tests/ui/inference/multiple-impl-apply-2.rs create mode 100644 tests/ui/inference/multiple-impl-apply-2.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b169f75796b3a..b75162c1e5add 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1548,6 +1548,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 28f537c87c4ee..47a456c731d7a 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -435,6 +435,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 0327a3097eca2..03d80cba0b80c 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -784,6 +784,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 a2e94492f8c23..ad1ac4f1fe62b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -495,6 +495,7 @@ symbols! { bitxor, bitxor_assign, black_box, + blanket_into_impl, block, bool, borrowck_graphviz_format, 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 f6dd7898fb28e..914510e5c01ed 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 @@ -25,7 +25,7 @@ use crate::errors::{ AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, SourceKindMultiSuggestion, SourceKindSubdiag, }; -use crate::infer::InferCtxt; +use crate::infer::{InferCtxt, InferCtxtExt}; pub enum TypeAnnotationNeeded { /// ```compile_fail,E0282 @@ -74,6 +74,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 { .. })) @@ -418,6 +426,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); @@ -451,17 +461,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 { @@ -557,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 } => { @@ -613,6 +685,122 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }), } } + + fn get_fully_qualified_path_suggestions_from_impls( + &self, + self_ty: Ty<'tcx>, + def_id: DefId, + target_type: 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.infcx.can_eq(param_env, impl_self_ty, self_ty) { + // 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 target_type { + 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 Some(assoc) = assocs.filter_by_name_unhygienic(name).next() else { + // The method isn't in this `impl`? 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 target_type { + 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 => { + paths.push(self.tcx.value_path_str_with_args(def_id, args)); + } + } + }); + paths + } } #[derive(Debug)] @@ -628,6 +816,7 @@ enum InferSourceKind<'tcx> { pattern_name: Option, ty: Ty<'tcx>, def_id: Option, + init_expr_hir_id: Option, }, ClosureArg { insert_span: Span, @@ -813,8 +1002,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() { @@ -1123,6 +1315,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 9ab4705785921..0f4ee00d7e7be 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -208,6 +208,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(); } @@ -237,6 +239,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0283, true, + obligation.param_env, + None, ) } else { struct_span_code_err!( @@ -477,6 +481,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0282, false, + obligation.param_env, + None, ) } @@ -496,6 +502,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { a.into(), TypeAnnotationNeeded::E0282, true, + obligation.param_env, + None, ) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { @@ -526,6 +534,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + Some(data), ) .with_note(format!("cannot satisfy `{predicate}`")) } else { @@ -556,6 +566,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { arg, TypeAnnotationNeeded::E0284, true, + obligation.param_env, + None, ); err } else { @@ -578,6 +590,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..7c78ae4cb8d76 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -30,8 +30,12 @@ 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 = <_ as Into<_>>::into(foo_impl) * 1u32; + | +++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +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/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..4f00d70cecc7e 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,12 @@ 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] = <_ as Into<_>>::into(Zeroes) { + | +++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +LL | if let [a, b, c] = >::into(Zeroes) { + | +++++++++++++++++++++++++++++++++++ ~ error[E0282]: type annotations needed --> $DIR/slice-pattern-refutable.rs:28:31 @@ -32,8 +40,12 @@ 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] = <_ as Into<_>>::into(Zeroes) { + | +++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +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..c543d79a80035 100644 --- a/tests/ui/pattern/slice-patterns-ambiguity.stderr +++ b/tests/ui/pattern/slice-patterns-ambiguity.stderr @@ -19,8 +19,16 @@ 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] = <_ as Into<_>>::into(Zeroes) { + | +++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +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 +40,16 @@ 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] = <_ as Into<_>>::into(Zeroes) { + | +++++++++++++++++++++ ~ +help: try using a fully qualified path to specify the expected types + | +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/suggestions/types/into-inference-needs-type.stderr b/tests/ui/suggestions/types/into-inference-needs-type.stderr index dd688f9028982..718c6b43143ea 100644 --- a/tests/ui/suggestions/types/into-inference-needs-type.stderr +++ b/tests/ui/suggestions/types/into-inference-needs-type.stderr @@ -8,7 +8,7 @@ LL | .into()?; = note: required for `FilterMap, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option> {Option::>::Some}>` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | -LL ~ let list = , _>, _> as Into>::into(vec +LL ~ let list = <_ as Into<_>>::into(vec LL | .iter() LL | .map(|s| s.strip_prefix("t")) LL ~ .filter_map(Option::Some))?; 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