@@ -24,6 +24,8 @@ use if_chain::if_chain;
24
24
use matches:: matches;
25
25
use rustc:: hir;
26
26
use rustc:: hir:: def:: Def ;
27
+ use rustc:: hir:: map:: DisambiguatedDefPathData ;
28
+ use rustc:: hir:: def_id:: CrateNum ;
27
29
use rustc:: hir:: def_id:: { DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
28
30
use rustc:: hir:: intravisit:: { NestedVisitorMap , Visitor } ;
29
31
use rustc:: hir:: Node ;
@@ -41,7 +43,6 @@ use rustc_errors::Applicability;
41
43
use syntax:: ast:: { self , LitKind } ;
42
44
use syntax:: attr;
43
45
use syntax:: source_map:: { Span , DUMMY_SP } ;
44
- use syntax:: symbol;
45
46
use syntax:: symbol:: { keywords, Symbol } ;
46
47
47
48
use crate :: reexport:: * ;
@@ -97,19 +98,97 @@ pub fn in_macro(span: Span) -> bool {
97
98
/// Used to store the absolute path to a type.
98
99
///
99
100
/// See `match_def_path` for usage.
100
- #[ derive( Debug ) ]
101
- pub struct AbsolutePathBuffer {
102
- pub names : Vec < symbol:: LocalInternedString > ,
101
+ pub struct AbsolutePathBuffer < ' a , ' tcx > {
102
+ pub tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
103
103
}
104
104
105
- impl ty:: item_path:: ItemPathBuffer for AbsolutePathBuffer {
106
- fn root_mode ( & self ) -> & ty:: item_path:: RootMode {
107
- const ABSOLUTE : & ty:: item_path:: RootMode = & ty:: item_path:: RootMode :: Absolute ;
108
- ABSOLUTE
105
+ use rustc:: ty:: print:: Printer ;
106
+
107
+ impl < ' tcx > Printer < ' tcx , ' tcx > for AbsolutePathBuffer < ' _ , ' tcx > {
108
+ type Error = !;
109
+
110
+ type Path = Vec < String > ;
111
+ type Region = ( ) ;
112
+ type Type = ( ) ;
113
+ type DynExistential = ( ) ;
114
+
115
+ fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > {
116
+ self . tcx
117
+ }
118
+
119
+ fn print_region (
120
+ self ,
121
+ _region : ty:: Region < ' _ > ,
122
+ ) -> Result < Self :: Region , Self :: Error > {
123
+ Ok ( ( ) )
124
+ }
125
+
126
+ fn print_type (
127
+ self ,
128
+ _ty : Ty < ' tcx > ,
129
+ ) -> Result < Self :: Type , Self :: Error > {
130
+ Ok ( ( ) )
131
+ }
132
+
133
+ fn print_dyn_existential (
134
+ self ,
135
+ _predicates : & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > ,
136
+ ) -> Result < Self :: DynExistential , Self :: Error > {
137
+ Ok ( ( ) )
109
138
}
110
139
111
- fn push ( & mut self , text : & str ) {
112
- self . names . push ( symbol:: Symbol :: intern ( text) . as_str ( ) ) ;
140
+ fn path_crate (
141
+ self ,
142
+ cnum : CrateNum ,
143
+ ) -> Result < Self :: Path , Self :: Error > {
144
+ Ok ( vec ! [ self . tcx. original_crate_name( cnum) . to_string( ) ] )
145
+ }
146
+ fn path_qualified (
147
+ self ,
148
+ self_ty : Ty < ' tcx > ,
149
+ trait_ref : Option < ty:: TraitRef < ' tcx > > ,
150
+ ) -> Result < Self :: Path , Self :: Error > {
151
+ // This shouldn't ever be needed, but just in case:
152
+ Ok ( vec ! [ match trait_ref {
153
+ Some ( trait_ref) => format!( "{:?}" , trait_ref) ,
154
+ None => format!( "<{}>" , self_ty) ,
155
+ } ] )
156
+ }
157
+
158
+ fn path_append_impl (
159
+ self ,
160
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
161
+ _disambiguated_data : & DisambiguatedDefPathData ,
162
+ self_ty : Ty < ' tcx > ,
163
+ trait_ref : Option < ty:: TraitRef < ' tcx > > ,
164
+ ) -> Result < Self :: Path , Self :: Error > {
165
+ let mut path = print_prefix ( self ) ?;
166
+
167
+ // This shouldn't ever be needed, but just in case:
168
+ path. push ( match trait_ref {
169
+ Some ( trait_ref) => {
170
+ format ! ( "<impl {} for {}>" , trait_ref, self_ty)
171
+ }
172
+ None => format ! ( "<impl {}>" , self_ty) ,
173
+ } ) ;
174
+
175
+ Ok ( path)
176
+ }
177
+ fn path_append (
178
+ self ,
179
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
180
+ disambiguated_data : & DisambiguatedDefPathData ,
181
+ ) -> Result < Self :: Path , Self :: Error > {
182
+ let mut path = print_prefix ( self ) ?;
183
+ path. push ( disambiguated_data. data . as_interned_str ( ) . to_string ( ) ) ;
184
+ Ok ( path)
185
+ }
186
+ fn path_generic_args (
187
+ self ,
188
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
189
+ _args : & [ Kind < ' tcx > ] ,
190
+ ) -> Result < Self :: Path , Self :: Error > {
191
+ print_prefix ( self )
113
192
}
114
193
}
115
194
@@ -121,12 +200,10 @@ impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
121
200
/// ```
122
201
///
123
202
/// See also the `paths` module.
124
- pub fn match_def_path ( tcx : TyCtxt < ' _ , ' _ , ' _ > , def_id : DefId , path : & [ & str ] ) -> bool {
125
- let mut apb = AbsolutePathBuffer { names : vec ! [ ] } ;
203
+ pub fn match_def_path < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId , path : & [ & str ] ) -> bool {
204
+ let names = AbsolutePathBuffer { tcx } . print_def_path ( def_id , & [ ] ) . unwrap ( ) ;
126
205
127
- tcx. push_item_path ( & mut apb, def_id, false ) ;
128
-
129
- apb. names . len ( ) == path. len ( ) && apb. names . into_iter ( ) . zip ( path. iter ( ) ) . all ( |( a, & b) | * a == * b)
206
+ names. len ( ) == path. len ( ) && names. into_iter ( ) . zip ( path. iter ( ) ) . all ( |( a, & b) | * a == * b)
130
207
}
131
208
132
209
/// Gets the absolute path of `def_id` as a vector of `&str`.
@@ -138,13 +215,8 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) ->
138
215
/// // The given `def_id` is that of an `Option` type
139
216
/// };
140
217
/// ```
141
- pub fn get_def_path ( tcx : TyCtxt < ' _ , ' _ , ' _ > , def_id : DefId ) -> Vec < & ' static str > {
142
- let mut apb = AbsolutePathBuffer { names : vec ! [ ] } ;
143
- tcx. push_item_path ( & mut apb, def_id, false ) ;
144
- apb. names
145
- . iter ( )
146
- . map ( syntax_pos:: symbol:: LocalInternedString :: get)
147
- . collect ( )
218
+ pub fn get_def_path < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Vec < String > {
219
+ AbsolutePathBuffer { tcx } . print_def_path ( def_id, & [ ] ) . unwrap ( )
148
220
}
149
221
150
222
/// Checks if type is struct, enum or union type with the given def path.
0 commit comments