1
1
use clippy_utils:: paths:: { PathNS , find_crates, lookup_path} ;
2
+ use itertools:: Itertools ;
2
3
use rustc_data_structures:: fx:: FxHashMap ;
3
4
use rustc_errors:: { Applicability , Diag } ;
4
5
use rustc_hir:: PrimTy ;
5
6
use rustc_hir:: def:: DefKind ;
6
7
use rustc_hir:: def_id:: DefIdMap ;
7
8
use rustc_middle:: ty:: TyCtxt ;
8
- use rustc_span:: { Span , Symbol } ;
9
+ use rustc_span:: { DUMMY_SP , Span , Symbol } ;
9
10
use serde:: de:: { self , Deserializer , Visitor } ;
10
11
use serde:: { Deserialize , Serialize , ser} ;
11
12
use std:: collections:: HashMap ;
12
13
use std:: fmt;
14
+ use std:: ops:: Deref ;
13
15
14
16
#[ derive( Debug , Deserialize ) ]
15
17
#[ serde( deny_unknown_fields) ]
@@ -18,11 +20,11 @@ pub struct Rename {
18
20
pub rename : String ,
19
21
}
20
22
21
- pub type ConfPathWithoutReplacement = ConfPath < false > ;
23
+ pub type ConfPathWithoutReplacement = ConfPath < String , false > ;
22
24
23
25
#[ derive( Debug , Serialize ) ]
24
- pub struct ConfPath < const REPLACEABLE : bool = true> {
25
- path : String ,
26
+ pub struct ConfPath < T = String , const REPLACEABLE : bool = true> {
27
+ path : T ,
26
28
reason : Option < String > ,
27
29
replacement : Option < String > ,
28
30
/// Setting `allow_invalid` to true suppresses a warning if `path` does not refer to an existing
@@ -38,7 +40,7 @@ pub struct ConfPath<const REPLACEABLE: bool = true> {
38
40
span : Span ,
39
41
}
40
42
41
- impl < ' de , const REPLACEABLE : bool > Deserialize < ' de > for ConfPath < REPLACEABLE > {
43
+ impl < ' de , const REPLACEABLE : bool > Deserialize < ' de > for ConfPath < String , REPLACEABLE > {
42
44
fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
43
45
where
44
46
D : Deserializer < ' de > ,
@@ -72,8 +74,8 @@ enum ConfPathEnum {
72
74
} ,
73
75
}
74
76
75
- impl < const REPLACEABLE : bool > ConfPath < REPLACEABLE > {
76
- pub fn path ( & self ) -> & str {
77
+ impl < T , const REPLACEABLE : bool > ConfPath < T , REPLACEABLE > {
78
+ pub fn path ( & self ) -> & T {
77
79
& self . path
78
80
}
79
81
@@ -101,6 +103,16 @@ impl<const REPLACEABLE: bool> ConfPath<REPLACEABLE> {
101
103
}
102
104
}
103
105
106
+ impl < T , const REPLACEABLE : bool > ConfPath < T , REPLACEABLE >
107
+ where
108
+ T : Deref ,
109
+ <T as Deref >:: Target : ToSymPath ,
110
+ {
111
+ pub fn to_sym_path ( & self ) -> Vec < Symbol > {
112
+ self . path ( ) . to_sym_path ( )
113
+ }
114
+ }
115
+
104
116
impl ConfPathEnum {
105
117
pub fn path ( & self ) -> & str {
106
118
let ( Self :: Simple ( path) | Self :: WithReason { path, .. } ) = self ;
@@ -130,24 +142,71 @@ impl ConfPathEnum {
130
142
}
131
143
}
132
144
145
+ pub trait ToSymPath {
146
+ fn to_sym_path ( & self ) -> Vec < Symbol > ;
147
+ }
148
+
149
+ impl ToSymPath for str {
150
+ fn to_sym_path ( & self ) -> Vec < Symbol > {
151
+ self . split ( "::" ) . map ( Symbol :: intern) . collect ( )
152
+ }
153
+ }
154
+
155
+ #[ derive( Clone , Copy , Debug ) ]
156
+ pub struct SymPath < ' a > ( pub & ' a [ Symbol ] ) ;
157
+
158
+ impl Deref for SymPath < ' _ > {
159
+ type Target = [ Symbol ] ;
160
+ fn deref ( & self ) -> & Self :: Target {
161
+ self . 0
162
+ }
163
+ }
164
+
165
+ impl fmt:: Display for SymPath < ' _ > {
166
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
167
+ f. write_str ( & self . 0 . iter ( ) . map ( Symbol :: to_string) . join ( "::" ) )
168
+ }
169
+ }
170
+
171
+ impl ToSymPath for [ Symbol ] {
172
+ fn to_sym_path ( & self ) -> Vec < Symbol > {
173
+ self . to_owned ( )
174
+ }
175
+ }
176
+
177
+ pub const fn conf_path_from_sym_path ( sym_path : & ' static [ Symbol ] ) -> ConfPath < SymPath < ' static > , false > {
178
+ ConfPath {
179
+ path : SymPath ( sym_path) ,
180
+ reason : None ,
181
+ replacement : None ,
182
+ allow_invalid : false ,
183
+ span : DUMMY_SP ,
184
+ }
185
+ }
186
+
133
187
/// Creates a map of disallowed items to the reason they were disallowed.
134
188
#[ allow( clippy:: type_complexity) ]
135
- pub fn create_conf_path_map < const REPLACEABLE : bool > (
189
+ pub fn create_conf_path_map < T , const REPLACEABLE : bool > (
136
190
tcx : TyCtxt < ' _ > ,
137
- conf_paths : & ' static [ ConfPath < REPLACEABLE > ] ,
191
+ conf_paths : & ' static [ ConfPath < T , REPLACEABLE > ] ,
138
192
ns : PathNS ,
139
193
def_kind_predicate : impl Fn ( DefKind ) -> bool ,
140
194
predicate_description : & str ,
141
195
allow_prim_tys : bool ,
142
196
) -> (
143
- DefIdMap < ( & ' static str , & ' static ConfPath < REPLACEABLE > ) > ,
144
- FxHashMap < PrimTy , ( & ' static str , & ' static ConfPath < REPLACEABLE > ) > ,
145
- ) {
146
- let mut def_ids: DefIdMap < ( & ' static str , & ConfPath < REPLACEABLE > ) > = DefIdMap :: default ( ) ;
147
- let mut prim_tys: FxHashMap < PrimTy , ( & ' static str , & ConfPath < REPLACEABLE > ) > = FxHashMap :: default ( ) ;
197
+ DefIdMap < ( & ' static <T as Deref >:: Target , & ' static ConfPath < T , REPLACEABLE > ) > ,
198
+ FxHashMap < PrimTy , ( & ' static <T as Deref >:: Target , & ' static ConfPath < T , REPLACEABLE > ) > ,
199
+ )
200
+ where
201
+ T : Deref + fmt:: Display ,
202
+ <T as Deref >:: Target : ToSymPath ,
203
+ {
204
+ let mut def_ids: DefIdMap < ( & ' static <T as Deref >:: Target , & ConfPath < T , REPLACEABLE > ) > = DefIdMap :: default ( ) ;
205
+ let mut prim_tys: FxHashMap < PrimTy , ( & ' static <T as Deref >:: Target , & ConfPath < T , REPLACEABLE > ) > =
206
+ FxHashMap :: default ( ) ;
148
207
for conf_path in conf_paths {
149
208
let path = conf_path. path ( ) ;
150
- let sym_path: Vec < Symbol > = path. split ( "::" ) . map ( Symbol :: intern ) . collect ( ) ;
209
+ let sym_path = path. to_sym_path ( ) ;
151
210
let mut resolutions = lookup_path ( tcx, ns, & sym_path) ;
152
211
resolutions. retain ( |& def_id| def_kind_predicate ( tcx. def_kind ( def_id) ) ) ;
153
212
0 commit comments