diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 0f5ba26337a15..dcab571eedf56 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -435,6 +435,22 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { &self, num_params_to_take: usize, ) -> String { + let is_in_a_method_call = self + .tcx + .hir() + .parent_iter(self.path_segment.hir_id) + .skip(1) + .find_map(|(_, node)| match node { + hir::Node::Expr(expr) => Some(expr), + _ => None, + }) + .is_some_and(|expr| { + matches!( + expr.kind, + hir::ExprKind::MethodCall(hir::PathSegment { args: Some(_), .. }, ..) + ) + }); + let fn_sig = self.tcx.hir().get_if_local(self.def_id).and_then(hir::Node::fn_sig); let is_used_in_input = |def_id| { fn_sig.is_some_and(|fn_sig| { @@ -453,14 +469,17 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .skip(self.params_offset + self.num_provided_type_or_const_args()) .take(num_params_to_take) .map(|param| match param.kind { - // This is being inferred from the item's inputs, no need to set it. - ty::GenericParamDefKind::Type { .. } if is_used_in_input(param.def_id) => { - "_".to_string() + // If it's in method call (turbofish), it might be inferred from the expression (e.g. `.collect::>()`) + // If it is being inferred from the item's inputs, no need to set it. + ty::GenericParamDefKind::Type { .. } + if is_in_a_method_call || is_used_in_input(param.def_id) => + { + "_" } - _ => param.name.to_string(), + _ => param.name.as_str(), }) - .collect::>() - .join(", ") + .intersperse(", ") + .collect() } fn get_unbound_associated_types(&self) -> Vec { diff --git a/tests/ui/generics/generic-type-less-params-with-defaults.rs b/tests/ui/generics/generic-type-less-params-with-defaults.rs index 6b877ab8aee6a..d04b1c80d3406 100644 --- a/tests/ui/generics/generic-type-less-params-with-defaults.rs +++ b/tests/ui/generics/generic-type-less-params-with-defaults.rs @@ -5,7 +5,23 @@ struct Heap; struct Vec( marker::PhantomData<(T,A)>); +struct HashMap(marker::PhantomData<(K,V,S)>); + fn main() { let _: Vec; //~^ ERROR missing generics for struct `Vec` + //~| SUGGESTION + + let _x = (1..10).collect::(); + //~^ ERROR missing generics for struct `HashMap` + //~| SUGGESTION <_, _> + + ().extend::<[(); 0]>({ + fn not_the_extend() { + let _: Vec; + //~^ ERROR missing generics for struct `Vec` + //~| SUGGESTION + } + [] + }); } diff --git a/tests/ui/generics/generic-type-less-params-with-defaults.stderr b/tests/ui/generics/generic-type-less-params-with-defaults.stderr index 6f79b09f6cd33..a6771a6d5c836 100644 --- a/tests/ui/generics/generic-type-less-params-with-defaults.stderr +++ b/tests/ui/generics/generic-type-less-params-with-defaults.stderr @@ -1,5 +1,5 @@ error[E0107]: missing generics for struct `Vec` - --> $DIR/generic-type-less-params-with-defaults.rs:9:12 + --> $DIR/generic-type-less-params-with-defaults.rs:11:12 | LL | let _: Vec; | ^^^ expected at least 1 generic argument @@ -14,6 +14,38 @@ help: add missing generic argument LL | let _: Vec; | +++ -error: aborting due to 1 previous error +error[E0107]: missing generics for struct `HashMap` + --> $DIR/generic-type-less-params-with-defaults.rs:15:32 + | +LL | let _x = (1..10).collect::(); + | ^^^^^^^ expected at least 2 generic arguments + | +note: struct defined here, with at least 2 generic parameters: `K`, `V` + --> $DIR/generic-type-less-params-with-defaults.rs:8:8 + | +LL | struct HashMap(marker::PhantomData<(K,V,S)>); + | ^^^^^^^ - - +help: add missing generic arguments + | +LL | let _x = (1..10).collect::>(); + | ++++++ + +error[E0107]: missing generics for struct `Vec` + --> $DIR/generic-type-less-params-with-defaults.rs:21:20 + | +LL | let _: Vec; + | ^^^ expected at least 1 generic argument + | +note: struct defined here, with at least 1 generic parameter: `T` + --> $DIR/generic-type-less-params-with-defaults.rs:5:8 + | +LL | struct Vec( + | ^^^ - +help: add missing generic argument + | +LL | let _: Vec; + | +++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0107`.