@@ -6,8 +6,9 @@ use crate::astconv::{
6
6
use crate :: errors:: AssocTypeBindingNotAllowed ;
7
7
use crate :: structured_errors:: { StructuredDiagnostic , WrongNumberOfGenericArgs } ;
8
8
use rustc_ast:: ast:: ParamKindOrd ;
9
- use rustc_errors:: { struct_span_err, Applicability , ErrorReported } ;
9
+ use rustc_errors:: { struct_span_err, Applicability , DiagnosticBuilder , ErrorReported } ;
10
10
use rustc_hir as hir;
11
+ use rustc_hir:: def:: { DefKind , Res } ;
11
12
use rustc_hir:: def_id:: DefId ;
12
13
use rustc_hir:: GenericArg ;
13
14
use rustc_middle:: ty:: {
@@ -43,23 +44,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
43
44
}
44
45
}
45
46
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
+
46
60
// Specific suggestion set for diagnostics
47
61
match ( arg, & param. kind ) {
48
62
(
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) ,
63
98
(
64
99
GenericArg :: Type ( hir:: Ty { kind : hir:: TyKind :: Array ( _, len) , .. } ) ,
65
100
GenericParamDefKind :: Const { .. } ,
0 commit comments