@@ -24,6 +24,8 @@ use if_chain::if_chain;
2424use matches:: matches;
2525use rustc:: hir;
2626use rustc:: hir:: def:: Def ;
27+ use rustc:: hir:: map:: DisambiguatedDefPathData ;
28+ use rustc:: hir:: def_id:: CrateNum ;
2729use rustc:: hir:: def_id:: { DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
2830use rustc:: hir:: intravisit:: { NestedVisitorMap , Visitor } ;
2931use rustc:: hir:: Node ;
@@ -41,7 +43,6 @@ use rustc_errors::Applicability;
4143use syntax:: ast:: { self , LitKind } ;
4244use syntax:: attr;
4345use syntax:: source_map:: { Span , DUMMY_SP } ;
44- use syntax:: symbol;
4546use syntax:: symbol:: { keywords, Symbol } ;
4647
4748use crate :: reexport:: * ;
@@ -97,19 +98,97 @@ pub fn in_macro(span: Span) -> bool {
9798/// Used to store the absolute path to a type.
9899///
99100/// 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 > ,
103103}
104104
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 ( ( ) )
109138 }
110139
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 )
113192 }
114193}
115194
@@ -121,12 +200,10 @@ impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
121200/// ```
122201///
123202/// 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 ( ) ;
126205
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)
130207}
131208
132209/// 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]) ->
138215/// // The given `def_id` is that of an `Option` type
139216/// };
140217/// ```
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 ( )
148220}
149221
150222/// Checks if type is struct, enum or union type with the given def path.
0 commit comments