@@ -4,11 +4,11 @@ use rustc_abi::ExternAbi;
44use rustc_errors:: codes:: * ;
55use rustc_errors:: {
66 Applicability , Diag , DiagCtxtHandle , DiagSymbolList , Diagnostic , EmissionGuarantee , Level ,
7- MultiSpan ,
7+ MultiSpan , listify ,
88} ;
99use rustc_hir:: limit:: Limit ;
1010use rustc_macros:: { Diagnostic , LintDiagnostic , Subdiagnostic } ;
11- use rustc_middle:: ty:: Ty ;
11+ use rustc_middle:: ty:: { self , Ty } ;
1212use rustc_span:: { Ident , Span , Symbol } ;
1313
1414use crate :: fluent_generated as fluent;
@@ -400,35 +400,58 @@ pub(crate) struct UnconstrainedOpaqueType {
400400 pub what : & ' static str ,
401401}
402402
403- pub ( crate ) struct MissingTypeParams {
403+ pub ( crate ) struct MissingGenericParams {
404404 pub span : Span ,
405405 pub def_span : Span ,
406406 pub span_snippet : Option < String > ,
407- pub missing_type_params : Vec < Symbol > ,
407+ pub missing_generic_params : Vec < ( Symbol , ty :: GenericParamDefKind ) > ,
408408 pub empty_generic_args : bool ,
409409}
410410
411- // Manual implementation of `Diagnostic` to be able to call `span_to_snippet`.
412- impl < ' a , G : EmissionGuarantee > Diagnostic < ' a , G > for MissingTypeParams {
411+ // FIXME: This doesn't need to be a manual impl!
412+ impl < ' a , G : EmissionGuarantee > Diagnostic < ' a , G > for MissingGenericParams {
413413 #[ track_caller]
414414 fn into_diag ( self , dcx : DiagCtxtHandle < ' a > , level : Level ) -> Diag < ' a , G > {
415- let mut err = Diag :: new ( dcx, level, fluent:: hir_analysis_missing_type_params ) ;
415+ let mut err = Diag :: new ( dcx, level, fluent:: hir_analysis_missing_generic_params ) ;
416416 err. span ( self . span ) ;
417417 err. code ( E0393 ) ;
418- err. arg ( "parameterCount" , self . missing_type_params . len ( ) ) ;
418+ err. span_label ( self . def_span , fluent:: hir_analysis_label) ;
419+
420+ enum Descr {
421+ Generic ,
422+ Type ,
423+ Const ,
424+ }
425+
426+ let mut descr = None ;
427+ for ( _, kind) in & self . missing_generic_params {
428+ descr = match ( & descr, kind) {
429+ ( None , ty:: GenericParamDefKind :: Type { .. } ) => Some ( Descr :: Type ) ,
430+ ( None , ty:: GenericParamDefKind :: Const { .. } ) => Some ( Descr :: Const ) ,
431+ ( Some ( Descr :: Type ) , ty:: GenericParamDefKind :: Const { .. } )
432+ | ( Some ( Descr :: Const ) , ty:: GenericParamDefKind :: Type { .. } ) => {
433+ Some ( Descr :: Generic )
434+ }
435+ _ => continue ,
436+ }
437+ }
438+
439+ err. arg (
440+ "descr" ,
441+ match descr. unwrap ( ) {
442+ Descr :: Generic => "generic" ,
443+ Descr :: Type => "type" ,
444+ Descr :: Const => "const" ,
445+ } ,
446+ ) ;
447+ err. arg ( "parameterCount" , self . missing_generic_params . len ( ) ) ;
419448 err. arg (
420449 "parameters" ,
421- self . missing_type_params
422- . iter ( )
423- . map ( |n| format ! ( "`{n}`" ) )
424- . collect :: < Vec < _ > > ( )
425- . join ( ", " ) ,
450+ listify ( & self . missing_generic_params , |( n, _) | format ! ( "`{n}`" ) ) . unwrap ( ) ,
426451 ) ;
427452
428- err. span_label ( self . def_span , fluent:: hir_analysis_label) ;
429-
430453 let mut suggested = false ;
431- // Don't suggest setting the type params if there are some already: the order is
454+ // Don't suggest setting the generic params if there are some already: The order is
432455 // tricky to get right and the user will already know what the syntax is.
433456 if let Some ( snippet) = self . span_snippet
434457 && self . empty_generic_args
@@ -438,16 +461,16 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams {
438461 // we would have to preserve the right order. For now, as clearly the user is
439462 // aware of the syntax, we do nothing.
440463 } else {
441- // The user wrote `Iterator `, so we don't have a type we can suggest, but at
442- // least we can clue them to the correct syntax `Iterator<Type >`.
464+ // The user wrote `Trait `, so we don't have a type we can suggest, but at
465+ // least we can clue them to the correct syntax `Trait</* Term */ >`.
443466 err. span_suggestion_verbose (
444467 self . span . shrink_to_hi ( ) ,
445468 fluent:: hir_analysis_suggestion,
446469 format ! (
447470 "<{}>" ,
448- self . missing_type_params
471+ self . missing_generic_params
449472 . iter( )
450- . map( |n| n . to_string ( ) )
473+ . map( |( n , _ ) | format! ( "/* {n} */" ) )
451474 . collect:: <Vec <_>>( )
452475 . join( ", " )
453476 ) ,
0 commit comments