From e485708b84b357a8fc40d7e0550042f0ca6c2920 Mon Sep 17 00:00:00 2001 From: arferreira Date: Thu, 12 Mar 2026 17:39:29 -0400 Subject: [PATCH] Point turbofish inference errors at the uninferred generic arg --- .../error_reporting/infer/need_type_info.rs | 24 ++++++++++++++----- .../generic_const_exprs/issue-105608.stderr | 4 ++-- .../inference/useless-turbofish-suggestion.rs | 11 ++++++--- .../useless-turbofish-suggestion.stderr | 14 +++++++---- tests/ui/issues/issue-23041.stderr | 4 ++-- .../issue-42234-unknown-receiver-type.stderr | 4 ++-- 6 files changed, 42 insertions(+), 19 deletions(-) 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 629bd30d88e8..921fab554348 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 @@ -1260,21 +1260,33 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { have_turbofish, } = args; let generics = tcx.generics_of(generics_def_id); - if let Some(mut argument_index) = generics + if let Some((argument_index, _)) = generics .own_args(args) .iter() - .position(|&arg| self.generic_arg_contains_target(arg)) + .enumerate() + .find(|&(_, &arg)| self.generic_arg_contains_target(arg)) { - if generics.has_own_self() { - argument_index += 1; - } let args = self.tecx.resolve_vars_if_possible(args); let generic_args = &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..]; let span = match expr.kind { - ExprKind::MethodCall(path, ..) => path.ident.span, + ExprKind::MethodCall(segment, ..) + if have_turbofish + && let Some(hir_args) = segment.args + && let Some(idx) = + argument_index.checked_sub(generics.own_counts().lifetimes) + && let Some(arg) = + hir_args.args.get(hir_args.num_lifetime_params() + idx) => + { + arg.span() + } + ExprKind::MethodCall(segment, ..) => segment.ident.span, _ => expr.span, }; + let mut argument_index = argument_index; + if generics.has_own_self() { + argument_index += 1; + } self.update_infer_source(InferSource { span, diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr index cc35035edf95..dede51416bfa 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/issue-105608.rs:13:22 + --> $DIR/issue-105608.rs:13:28 | LL | Combination::<0>.and::<_>().and::<_>(); - | ^^^ cannot infer type of the type parameter `M` declared on the method `and` + | ^ cannot infer type of the type parameter `M` declared on the method `and` error: aborting due to 1 previous error diff --git a/tests/ui/inference/useless-turbofish-suggestion.rs b/tests/ui/inference/useless-turbofish-suggestion.rs index ed86df6296ca..64dbfff64c52 100644 --- a/tests/ui/inference/useless-turbofish-suggestion.rs +++ b/tests/ui/inference/useless-turbofish-suggestion.rs @@ -4,8 +4,8 @@ // rewriting them — the suggestion just rewrites user syntax into // fully-qualified form without resolving anything. // -// The span still points at the method name rather than the unresolved `_`; -// fixing that is left as future work. +// When a turbofish is present, the diagnostic points at the specific +// uninferred generic argument rather than the method name. struct S; @@ -15,11 +15,16 @@ fn f(self, _a: A) -> B { } } -fn with_turbofish() { +fn turbofish_second_arg() { S.f::(42); //~^ ERROR type annotations needed } +fn turbofish_first_arg() { + S.f::<_, _>(42); + //~^ ERROR type annotations needed +} + fn without_turbofish() { S.f(42); //~^ ERROR type annotations needed diff --git a/tests/ui/inference/useless-turbofish-suggestion.stderr b/tests/ui/inference/useless-turbofish-suggestion.stderr index 25b05801aa47..ccd30b415f65 100644 --- a/tests/ui/inference/useless-turbofish-suggestion.stderr +++ b/tests/ui/inference/useless-turbofish-suggestion.stderr @@ -1,11 +1,17 @@ error[E0282]: type annotations needed - --> $DIR/useless-turbofish-suggestion.rs:19:7 + --> $DIR/useless-turbofish-suggestion.rs:19:16 | LL | S.f::(42); - | ^ cannot infer type of the type parameter `B` declared on the method `f` + | ^ cannot infer type of the type parameter `B` declared on the method `f` error[E0282]: type annotations needed - --> $DIR/useless-turbofish-suggestion.rs:24:7 + --> $DIR/useless-turbofish-suggestion.rs:24:14 + | +LL | S.f::<_, _>(42); + | ^ cannot infer type of the type parameter `B` declared on the method `f` + +error[E0282]: type annotations needed + --> $DIR/useless-turbofish-suggestion.rs:29:7 | LL | S.f(42); | ^ cannot infer type of the type parameter `B` declared on the method `f` @@ -15,6 +21,6 @@ help: consider specifying the generic arguments LL | S.f::(42); | ++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-23041.stderr b/tests/ui/issues/issue-23041.stderr index 4d7266c7c98d..b348a8695f6f 100644 --- a/tests/ui/issues/issue-23041.stderr +++ b/tests/ui/issues/issue-23041.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/issue-23041.rs:6:7 + --> $DIR/issue-23041.rs:6:22 | LL | b.downcast_ref::_>(); - | ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` + | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` error: aborting due to 1 previous error diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.stderr index f16006a8e085..9ebe7d64584d 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.stderr @@ -12,10 +12,10 @@ LL | let x: Option<_> = None::; | +++++ error[E0282]: type annotations needed - --> $DIR/issue-42234-unknown-receiver-type.rs:12:10 + --> $DIR/issue-42234-unknown-receiver-type.rs:12:16 | LL | .sum::<_>() - | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` + | ^ cannot infer type of the type parameter `S` declared on the method `sum` error: aborting due to 2 previous errors