11use clippy_utils:: paths:: { PathNS , find_crates, lookup_path} ;
2+ use itertools:: Itertools ;
23use rustc_data_structures:: fx:: FxHashMap ;
34use rustc_errors:: { Applicability , Diag } ;
45use rustc_hir:: PrimTy ;
56use rustc_hir:: def:: DefKind ;
67use rustc_hir:: def_id:: DefIdMap ;
78use rustc_middle:: ty:: TyCtxt ;
8- use rustc_span:: { Span , Symbol } ;
9+ use rustc_span:: { DUMMY_SP , Span , Symbol } ;
910use serde:: de:: { self , Deserializer , Visitor } ;
1011use serde:: { Deserialize , Serialize , ser} ;
1112use std:: collections:: HashMap ;
1213use std:: fmt;
14+ use std:: ops:: Deref ;
1315
1416#[ derive( Debug , Deserialize ) ]
1517#[ serde( deny_unknown_fields) ]
@@ -18,11 +20,11 @@ pub struct Rename {
1820 pub rename : String ,
1921}
2022
21- pub type ConfPathWithoutReplacement = ConfPath < false > ;
23+ pub type ConfPathWithoutReplacement = ConfPath < String , false > ;
2224
2325#[ 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 ,
2628 reason : Option < String > ,
2729 replacement : Option < String > ,
2830 /// 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> {
3840 span : Span ,
3941}
4042
41- impl < ' de , const REPLACEABLE : bool > Deserialize < ' de > for ConfPath < REPLACEABLE > {
43+ impl < ' de , const REPLACEABLE : bool > Deserialize < ' de > for ConfPath < String , REPLACEABLE > {
4244 fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
4345 where
4446 D : Deserializer < ' de > ,
@@ -72,8 +74,8 @@ enum ConfPathEnum {
7274 } ,
7375}
7476
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 {
7779 & self . path
7880 }
7981
@@ -101,6 +103,16 @@ impl<const REPLACEABLE: bool> ConfPath<REPLACEABLE> {
101103 }
102104}
103105
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+
104116impl ConfPathEnum {
105117 pub fn path ( & self ) -> & str {
106118 let ( Self :: Simple ( path) | Self :: WithReason { path, .. } ) = self ;
@@ -130,24 +142,71 @@ impl ConfPathEnum {
130142 }
131143}
132144
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+
133187/// Creates a map of disallowed items to the reason they were disallowed.
134188#[ 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 > (
136190 tcx : TyCtxt < ' _ > ,
137- conf_paths : & ' static [ ConfPath < REPLACEABLE > ] ,
191+ conf_paths : & ' static [ ConfPath < T , REPLACEABLE > ] ,
138192 ns : PathNS ,
139193 def_kind_predicate : impl Fn ( DefKind ) -> bool ,
140194 predicate_description : & str ,
141195 allow_prim_tys : bool ,
142196) -> (
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 ( ) ;
148207 for conf_path in conf_paths {
149208 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 ( ) ;
151210 let mut resolutions = lookup_path ( tcx, ns, & sym_path) ;
152211 resolutions. retain ( |& def_id| def_kind_predicate ( tcx. def_kind ( def_id) ) ) ;
153212
0 commit comments