1
+ use crate :: hir:: def:: Namespace ;
1
2
use crate :: hir:: map:: DefPathData ;
2
3
use crate :: hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
3
4
use crate :: ty:: { self , DefIdTree , Ty , TyCtxt } ;
5
+ use crate :: ty:: print:: PrintCx ;
6
+ use crate :: ty:: subst:: { Subst , Substs } ;
4
7
use crate :: middle:: cstore:: { ExternCrate , ExternCrateSource } ;
5
- use ty:: print:: PrintCx ;
6
8
use syntax:: ast;
7
9
use syntax:: symbol:: { keywords, Symbol } ;
8
10
@@ -54,18 +56,48 @@ pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
54
56
}
55
57
56
58
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
59
+ // HACK(eddyb) get rid of `item_path_str` and/or pass `Namespace` explicitly always
60
+ // (but also some things just print a `DefId` generally so maybe we need this?)
61
+ fn guess_def_namespace ( self , def_id : DefId ) -> Namespace {
62
+ match self . def_key ( def_id) . disambiguated_data . data {
63
+ DefPathData :: ValueNs ( ..) |
64
+ DefPathData :: EnumVariant ( ..) |
65
+ DefPathData :: Field ( ..) |
66
+ DefPathData :: AnonConst |
67
+ DefPathData :: ClosureExpr |
68
+ DefPathData :: StructCtor => Namespace :: ValueNS ,
69
+
70
+ DefPathData :: MacroDef ( ..) => Namespace :: MacroNS ,
71
+
72
+ _ => Namespace :: TypeNS ,
73
+ }
74
+ }
75
+
57
76
/// Returns a string identifying this `DefId`. This string is
58
77
/// suitable for user output. It is relative to the current crate
59
78
/// root, unless with_forced_absolute_paths was used.
60
- pub fn item_path_str ( self , def_id : DefId ) -> String {
61
- debug ! ( "item_path_str: def_id={:?}" , def_id) ;
79
+ pub fn item_path_str_with_substs_and_ns (
80
+ self ,
81
+ def_id : DefId ,
82
+ substs : Option < & Substs < ' tcx > > ,
83
+ ns : Namespace ,
84
+ ) -> String {
85
+ debug ! ( "item_path_str: def_id={:?}, substs={:?}, ns={:?}" , def_id, substs, ns) ;
62
86
if FORCE_ABSOLUTE . with ( |force| force. get ( ) ) {
63
- PrintCx :: new ( self , AbsolutePathPrinter ) . print_item_path ( def_id)
87
+ PrintCx :: new ( self , AbsolutePathPrinter ) . print_item_path ( def_id, substs , ns )
64
88
} else {
65
- PrintCx :: new ( self , LocalPathPrinter ) . print_item_path ( def_id)
89
+ PrintCx :: new ( self , LocalPathPrinter ) . print_item_path ( def_id, substs , ns )
66
90
}
67
91
}
68
92
93
+ /// Returns a string identifying this def-id. This string is
94
+ /// suitable for user output. It is relative to the current crate
95
+ /// root, unless with_forced_absolute_paths was used.
96
+ pub fn item_path_str ( self , def_id : DefId ) -> String {
97
+ let ns = self . guess_def_namespace ( def_id) ;
98
+ self . item_path_str_with_substs_and_ns ( def_id, None , ns)
99
+ }
100
+
69
101
/// Returns a string identifying this local node-id.
70
102
pub fn node_path_str ( self , id : ast:: NodeId ) -> String {
71
103
self . item_path_str ( self . hir ( ) . local_def_id ( id) )
@@ -75,13 +107,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
75
107
/// suitable for user output. It always begins with a crate identifier.
76
108
pub fn absolute_item_path_str ( self , def_id : DefId ) -> String {
77
109
debug ! ( "absolute_item_path_str: def_id={:?}" , def_id) ;
78
- PrintCx :: new ( self , AbsolutePathPrinter ) . print_item_path ( def_id)
110
+ let ns = self . guess_def_namespace ( def_id) ;
111
+ PrintCx :: new ( self , AbsolutePathPrinter ) . print_item_path ( def_id, None , ns)
79
112
}
80
113
}
81
114
82
115
impl < P : ItemPathPrinter > PrintCx < ' a , ' gcx , ' tcx , P > {
83
- pub fn default_print_item_path ( & mut self , def_id : DefId ) -> P :: Path {
84
- debug ! ( "default_print_item_path: def_id={:?}" , def_id) ;
116
+ pub fn default_print_item_path (
117
+ & mut self ,
118
+ def_id : DefId ,
119
+ substs : Option < & Substs < ' tcx > > ,
120
+ ns : Namespace ,
121
+ ) -> P :: Path {
122
+ debug ! ( "default_print_item_path: def_id={:?}, substs={:?}, ns={:?}" , def_id, substs, ns) ;
85
123
let key = self . tcx . def_key ( def_id) ;
86
124
debug ! ( "default_print_item_path: key={:?}" , key) ;
87
125
match key. disambiguated_data . data {
@@ -91,7 +129,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
91
129
}
92
130
93
131
DefPathData :: Impl => {
94
- self . print_impl_path ( def_id)
132
+ self . print_impl_path ( def_id, substs , ns )
95
133
}
96
134
97
135
// Unclear if there is any value in distinguishing these.
@@ -117,18 +155,23 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
117
155
data @ DefPathData :: ImplTrait |
118
156
data @ DefPathData :: GlobalMetaData ( ..) => {
119
157
let parent_did = self . tcx . parent_def_id ( def_id) . unwrap ( ) ;
120
- let path = self . print_item_path ( parent_did) ;
158
+ let path = self . print_item_path ( parent_did, None , ns ) ;
121
159
self . path_append ( path, & data. as_interned_str ( ) . as_symbol ( ) . as_str ( ) )
122
160
} ,
123
161
124
162
DefPathData :: StructCtor => { // present `X` instead of `X::{{constructor}}`
125
163
let parent_def_id = self . tcx . parent_def_id ( def_id) . unwrap ( ) ;
126
- self . print_item_path ( parent_def_id)
164
+ self . print_item_path ( parent_def_id, substs , ns )
127
165
}
128
166
}
129
167
}
130
168
131
- fn default_print_impl_path ( & mut self , impl_def_id : DefId ) -> P :: Path {
169
+ fn default_print_impl_path (
170
+ & mut self ,
171
+ impl_def_id : DefId ,
172
+ substs : Option < & Substs < ' tcx > > ,
173
+ ns : Namespace ,
174
+ ) -> P :: Path {
132
175
debug ! ( "default_print_impl_path: impl_def_id={:?}" , impl_def_id) ;
133
176
let parent_def_id = self . tcx . parent_def_id ( impl_def_id) . unwrap ( ) ;
134
177
@@ -137,13 +180,19 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
137
180
// users may find it useful. Currently, we omit the parent if
138
181
// the impl is either in the same module as the self-type or
139
182
// as the trait.
140
- let self_ty = self . tcx . type_of ( impl_def_id) ;
183
+ let mut self_ty = self . tcx . type_of ( impl_def_id) ;
184
+ if let Some ( substs) = substs {
185
+ self_ty = self_ty. subst ( self . tcx , substs) ;
186
+ }
141
187
let in_self_mod = match characteristic_def_id_of_type ( self_ty) {
142
188
None => false ,
143
189
Some ( ty_def_id) => self . tcx . parent_def_id ( ty_def_id) == Some ( parent_def_id) ,
144
190
} ;
145
191
146
- let impl_trait_ref = self . tcx . impl_trait_ref ( impl_def_id) ;
192
+ let mut impl_trait_ref = self . tcx . impl_trait_ref ( impl_def_id) ;
193
+ if let Some ( substs) = substs {
194
+ impl_trait_ref = impl_trait_ref. subst ( self . tcx , substs) ;
195
+ }
147
196
let in_trait_mod = match impl_trait_ref {
148
197
None => false ,
149
198
Some ( trait_ref) => self . tcx . parent_def_id ( trait_ref. def_id ) == Some ( parent_def_id) ,
@@ -153,7 +202,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
153
202
// If the impl is not co-located with either self-type or
154
203
// trait-type, then fallback to a format that identifies
155
204
// the module more clearly.
156
- let path = self . print_item_path ( parent_def_id) ;
205
+ let path = self . print_item_path ( parent_def_id, None , ns ) ;
157
206
if let Some ( trait_ref) = impl_trait_ref {
158
207
return self . path_append ( path, & format ! ( "<impl {} for {}>" , trait_ref, self_ty) ) ;
159
208
} else {
@@ -174,15 +223,14 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
174
223
// anything other than a simple path.
175
224
match self_ty. sty {
176
225
ty:: Adt ( adt_def, substs) => {
177
- // FIXME(eddyb) always print without <> here.
178
- if substs. types ( ) . next ( ) . is_none ( ) { // ignore regions
179
- self . print_item_path ( adt_def. did )
180
- } else {
181
- self . path_impl ( & format ! ( "<{}>" , self_ty) )
182
- }
226
+ // FIXME(eddyb) this should recurse to build the path piecewise.
227
+ // self.print_item_path(adt_def.did, Some(substs), ns)
228
+ let mut s = String :: new ( ) ;
229
+ crate :: util:: ppaux:: parameterized ( & mut s, adt_def. did , substs, ns) . unwrap ( ) ;
230
+ self . path_impl ( & s)
183
231
}
184
232
185
- ty:: Foreign ( did) => self . print_item_path ( did) ,
233
+ ty:: Foreign ( did) => self . print_item_path ( did, None , ns ) ,
186
234
187
235
ty:: Bool |
188
236
ty:: Char |
@@ -263,11 +311,21 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
263
311
pub trait ItemPathPrinter : Sized {
264
312
type Path ;
265
313
266
- fn print_item_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , def_id : DefId ) -> Self :: Path {
267
- self . default_print_item_path ( def_id)
314
+ fn print_item_path (
315
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
316
+ def_id : DefId ,
317
+ substs : Option < & Substs < ' tcx > > ,
318
+ ns : Namespace ,
319
+ ) -> Self :: Path {
320
+ self . default_print_item_path ( def_id, substs, ns)
268
321
}
269
- fn print_impl_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , impl_def_id : DefId ) -> Self :: Path {
270
- self . default_print_impl_path ( impl_def_id)
322
+ fn print_impl_path (
323
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
324
+ impl_def_id : DefId ,
325
+ substs : Option < & Substs < ' tcx > > ,
326
+ ns : Namespace ,
327
+ ) -> Self :: Path {
328
+ self . default_print_impl_path ( impl_def_id, substs, ns)
271
329
}
272
330
273
331
fn path_crate ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , cnum : CrateNum ) -> Self :: Path ;
@@ -312,6 +370,7 @@ impl LocalPathPrinter {
312
370
fn try_print_visible_item_path (
313
371
self : & mut PrintCx < ' _ , ' _ , ' _ , Self > ,
314
372
def_id : DefId ,
373
+ ns : Namespace ,
315
374
) -> Option < <Self as ItemPathPrinter >:: Path > {
316
375
debug ! ( "try_print_visible_item_path: def_id={:?}" , def_id) ;
317
376
@@ -343,7 +402,7 @@ impl LocalPathPrinter {
343
402
} ) => {
344
403
debug ! ( "try_print_visible_item_path: def_id={:?}" , def_id) ;
345
404
let path = if !span. is_dummy ( ) {
346
- self . print_item_path ( def_id)
405
+ self . print_item_path ( def_id, None , ns )
347
406
} else {
348
407
self . path_crate ( cnum)
349
408
} ;
@@ -376,7 +435,7 @@ impl LocalPathPrinter {
376
435
}
377
436
378
437
let visible_parent = visible_parent_map. get ( & def_id) . cloned ( ) ?;
379
- let path = self . try_print_visible_item_path ( visible_parent) ?;
438
+ let path = self . try_print_visible_item_path ( visible_parent, ns ) ?;
380
439
let actual_parent = self . tcx . parent ( def_id) ;
381
440
382
441
let data = cur_def_key. disambiguated_data . data ;
@@ -444,11 +503,21 @@ impl LocalPathPrinter {
444
503
impl ItemPathPrinter for LocalPathPrinter {
445
504
type Path = String ;
446
505
447
- fn print_item_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , def_id : DefId ) -> Self :: Path {
448
- self . try_print_visible_item_path ( def_id)
449
- . unwrap_or_else ( || self . default_print_item_path ( def_id) )
506
+ fn print_item_path (
507
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
508
+ def_id : DefId ,
509
+ substs : Option < & Substs < ' tcx > > ,
510
+ ns : Namespace ,
511
+ ) -> Self :: Path {
512
+ self . try_print_visible_item_path ( def_id, ns)
513
+ . unwrap_or_else ( || self . default_print_item_path ( def_id, substs, ns) )
450
514
}
451
- fn print_impl_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , impl_def_id : DefId ) -> Self :: Path {
515
+ fn print_impl_path (
516
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
517
+ impl_def_id : DefId ,
518
+ substs : Option < & Substs < ' tcx > > ,
519
+ ns : Namespace ,
520
+ ) -> Self :: Path {
452
521
// Always use types for non-local impls, where types are always
453
522
// available, and filename/line-number is mostly uninteresting.
454
523
let use_types = !impl_def_id. is_local ( ) || {
@@ -463,12 +532,12 @@ impl ItemPathPrinter for LocalPathPrinter {
463
532
// only occur very early in the compiler pipeline.
464
533
// FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
465
534
let parent_def_id = self . tcx . parent_def_id ( impl_def_id) . unwrap ( ) ;
466
- let path = self . print_item_path ( parent_def_id) ;
535
+ let path = self . print_item_path ( parent_def_id, None , ns ) ;
467
536
let span = self . tcx . def_span ( impl_def_id) ;
468
537
return self . path_append ( path, & format ! ( "<impl at {:?}>" , span) ) ;
469
538
}
470
539
471
- self . default_print_impl_path ( impl_def_id)
540
+ self . default_print_impl_path ( impl_def_id, substs , ns )
472
541
}
473
542
474
543
fn path_crate ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , cnum : CrateNum ) -> Self :: Path {
0 commit comments