@@ -2764,14 +2764,39 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
27642764
27652765 let ( msg, sugg) = match source {
27662766 PathSource :: Type | PathSource :: PreciseCapturingArg ( TypeNS ) => {
2767- ( "you might be missing a type parameter" , ident)
2767+ ( "you might be missing a type parameter" , ident. clone ( ) )
27682768 }
27692769 PathSource :: Expr ( _) | PathSource :: PreciseCapturingArg ( ValueNS ) => (
27702770 "you might be missing a const parameter" ,
27712771 format ! ( "const {ident}: /* Type */" ) ,
27722772 ) ,
27732773 _ => return None ,
27742774 } ;
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+ }
27752800 let ( span, sugg) = if let [ .., param] = & generics. params [ ..] {
27762801 let span = if let [ .., bound] = & param. bounds [ ..] {
27772802 bound. span ( )
0 commit comments