@@ -6,8 +6,9 @@ use crate::astconv::{
66use crate :: errors:: AssocTypeBindingNotAllowed ;
77use crate :: structured_errors:: { StructuredDiagnostic , WrongNumberOfGenericArgs } ;
88use rustc_ast:: ast:: ParamKindOrd ;
9- use rustc_errors:: { struct_span_err, Applicability , ErrorReported } ;
9+ use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorReported } ;
1010use rustc_hir as hir;
11+ use rustc_hir:: def:: { DefKind , Res } ;
1112use rustc_hir:: def_id:: DefId ;
1213use rustc_hir:: GenericArg ;
1314use rustc_middle:: ty:: {
@@ -43,23 +44,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
4344 }
4445 }
4546
47+ let add_braces_suggestion = |arg : & GenericArg < ' _ > , err : & mut DiagnosticBuilder < ' _ > | {
48+ let suggestions = vec ! [
49+ ( arg. span( ) . shrink_to_lo( ) , String :: from( "{ " ) ) ,
50+ ( arg. span( ) . shrink_to_hi( ) , String :: from( " }" ) ) ,
51+ ] ;
52+ err. multipart_suggestion (
53+ "if this generic argument was intended as a const parameter, \
54+ surround it with braces",
55+ suggestions,
56+ Applicability :: MaybeIncorrect ,
57+ ) ;
58+ } ;
59+
4660 // Specific suggestion set for diagnostics
4761 match ( arg, & param. kind ) {
4862 (
49- GenericArg :: Type ( hir:: Ty { kind : hir:: TyKind :: Path { .. } , .. } ) ,
50- GenericParamDefKind :: Const { .. } ,
51- ) => {
52- let suggestions = vec ! [
53- ( arg. span( ) . shrink_to_lo( ) , String :: from( "{ " ) ) ,
54- ( arg. span( ) . shrink_to_hi( ) , String :: from( " }" ) ) ,
55- ] ;
56- err. multipart_suggestion (
57- "if this generic argument was intended as a const parameter, \
58- try surrounding it with braces:",
59- suggestions,
60- Applicability :: MaybeIncorrect ,
61- ) ;
62- }
63+ GenericArg :: Type ( hir:: Ty {
64+ kind : hir:: TyKind :: Path ( rustc_hir:: QPath :: Resolved ( _, path) ) ,
65+ ..
66+ } ) ,
67+ GenericParamDefKind :: Const ,
68+ ) => match path. res {
69+ Res :: Err => {
70+ add_braces_suggestion ( arg, & mut err) ;
71+ err. set_primary_message (
72+ "unresolved item provided when a constant was expected" ,
73+ )
74+ . emit ( ) ;
75+ return ;
76+ }
77+ Res :: Def ( DefKind :: TyParam , src_def_id) => {
78+ if let Some ( param_local_id) = param. def_id . as_local ( ) {
79+ let param_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( param_local_id) ;
80+ let param_name = tcx. hir ( ) . ty_param_name ( param_hir_id) ;
81+ let param_type = tcx. type_of ( param. def_id ) ;
82+ if param_type. is_suggestable ( ) {
83+ err. span_suggestion (
84+ tcx. def_span ( src_def_id) ,
85+ "consider changing this type paramater to a `const`-generic" ,
86+ format ! ( "const {}: {}" , param_name, param_type) ,
87+ Applicability :: MaybeIncorrect ,
88+ ) ;
89+ } ;
90+ }
91+ }
92+ _ => add_braces_suggestion ( arg, & mut err) ,
93+ } ,
94+ (
95+ GenericArg :: Type ( hir:: Ty { kind : hir:: TyKind :: Path ( _) , .. } ) ,
96+ GenericParamDefKind :: Const ,
97+ ) => add_braces_suggestion ( arg, & mut err) ,
6398 (
6499 GenericArg :: Type ( hir:: Ty { kind : hir:: TyKind :: Array ( _, len) , .. } ) ,
65100 GenericParamDefKind :: Const { .. } ,
0 commit comments