@@ -2764,14 +2764,39 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
2764
2764
2765
2765
let ( msg, sugg) = match source {
2766
2766
PathSource :: Type | PathSource :: PreciseCapturingArg ( TypeNS ) => {
2767
- ( "you might be missing a type parameter" , ident)
2767
+ ( "you might be missing a type parameter" , ident. clone ( ) )
2768
2768
}
2769
2769
PathSource :: Expr ( _) | PathSource :: PreciseCapturingArg ( ValueNS ) => (
2770
2770
"you might be missing a const parameter" ,
2771
2771
format ! ( "const {ident}: /* Type */" ) ,
2772
2772
) ,
2773
2773
_ => return None ,
2774
2774
} ;
2775
+
2776
+ // Heuristically determine whether a type name is likely intended to be a generic.
2777
+ //
2778
+ // We apply three rules:
2779
+ // 1. Short names (like `T`, `U`, `E`) are common for generics.
2780
+ // 2. Certain well-known names (e.g., `Item`, `Output`, `Error`) are commonly used as generics.
2781
+ // 3. Names in UpperCamelCase are more likely to be concrete types.
2782
+ //
2783
+ // This approach may produce false positives or negatives, but works well in most cases.
2784
+
2785
+ let common_generic_names: & [ & str ] = & [
2786
+ "Item" , "Output" , "Error" , "Target" , "Value" , "Args" ,
2787
+ "Res" , "Ret" , "This" , "Iter" , "Type" ,
2788
+ ] ;
2789
+ let is_common_generic = common_generic_names. contains ( & & * ident) ;
2790
+ let looks_like_camel_case = ident
2791
+ . chars ( )
2792
+ . next ( )
2793
+ . is_some_and ( |c| c. is_uppercase ( ) )
2794
+ && ident. chars ( ) . skip ( 1 ) . any ( |c| c. is_lowercase ( ) ) ;
2795
+
2796
+ // If it's not a known generic name and looks like a concrete type, skip the suggestion.
2797
+ if !is_common_generic && looks_like_camel_case && ident. len ( ) > 3 {
2798
+ return None ;
2799
+ }
2775
2800
let ( span, sugg) = if let [ .., param] = & generics. params [ ..] {
2776
2801
let span = if let [ .., bound] = & param. bounds [ ..] {
2777
2802
bound. span ( )
0 commit comments