1
+ use hir:: def:: Namespace ;
1
2
use hir:: map:: DefPathData ;
2
3
use hir:: def_id:: { CrateNum , DefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
3
4
use ty:: { self , DefIdTree , Ty , TyCtxt } ;
4
5
use ty:: print:: PrintCx ;
6
+ use ty:: subst:: { Subst , Substs } ;
5
7
use middle:: cstore:: { ExternCrate , ExternCrateSource } ;
6
8
use syntax:: ast;
7
9
use syntax:: symbol:: { keywords, Symbol } ;
@@ -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 def-id. 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.
@@ -116,18 +154,23 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
116
154
data @ DefPathData :: ImplTrait |
117
155
data @ DefPathData :: GlobalMetaData ( ..) => {
118
156
let parent_did = self . tcx . parent_def_id ( def_id) . unwrap ( ) ;
119
- let path = self . print_item_path ( parent_did) ;
157
+ let path = self . print_item_path ( parent_did, None , ns ) ;
120
158
self . path_append ( path, & data. as_interned_str ( ) . as_symbol ( ) . as_str ( ) )
121
159
} ,
122
160
123
161
DefPathData :: StructCtor => { // present `X` instead of `X::{{constructor}}`
124
162
let parent_def_id = self . tcx . parent_def_id ( def_id) . unwrap ( ) ;
125
- self . print_item_path ( parent_def_id)
163
+ self . print_item_path ( parent_def_id, substs , ns )
126
164
}
127
165
}
128
166
}
129
167
130
- fn default_print_impl_path ( & mut self , impl_def_id : DefId ) -> P :: Path {
168
+ fn default_print_impl_path (
169
+ & mut self ,
170
+ impl_def_id : DefId ,
171
+ substs : Option < & Substs < ' tcx > > ,
172
+ ns : Namespace ,
173
+ ) -> P :: Path {
131
174
debug ! ( "default_print_impl_path: impl_def_id={:?}" , impl_def_id) ;
132
175
let parent_def_id = self . tcx . parent_def_id ( impl_def_id) . unwrap ( ) ;
133
176
@@ -136,13 +179,19 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
136
179
// users may find it useful. Currently, we omit the parent if
137
180
// the impl is either in the same module as the self-type or
138
181
// as the trait.
139
- let self_ty = self . tcx . type_of ( impl_def_id) ;
182
+ let mut self_ty = self . tcx . type_of ( impl_def_id) ;
183
+ if let Some ( substs) = substs {
184
+ self_ty = self_ty. subst ( self . tcx , substs) ;
185
+ }
140
186
let in_self_mod = match characteristic_def_id_of_type ( self_ty) {
141
187
None => false ,
142
188
Some ( ty_def_id) => self . tcx . parent_def_id ( ty_def_id) == Some ( parent_def_id) ,
143
189
} ;
144
190
145
- let impl_trait_ref = self . tcx . impl_trait_ref ( impl_def_id) ;
191
+ let mut impl_trait_ref = self . tcx . impl_trait_ref ( impl_def_id) ;
192
+ if let Some ( substs) = substs {
193
+ impl_trait_ref = impl_trait_ref. subst ( self . tcx , substs) ;
194
+ }
146
195
let in_trait_mod = match impl_trait_ref {
147
196
None => false ,
148
197
Some ( trait_ref) => self . tcx . parent_def_id ( trait_ref. def_id ) == Some ( parent_def_id) ,
@@ -152,7 +201,7 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
152
201
// If the impl is not co-located with either self-type or
153
202
// trait-type, then fallback to a format that identifies
154
203
// the module more clearly.
155
- let path = self . print_item_path ( parent_def_id) ;
204
+ let path = self . print_item_path ( parent_def_id, None , ns ) ;
156
205
if let Some ( trait_ref) = impl_trait_ref {
157
206
return self . path_append ( path, & format ! ( "<impl {} for {}>" , trait_ref, self_ty) ) ;
158
207
} else {
@@ -173,15 +222,14 @@ impl<P: ItemPathPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
173
222
// anything other than a simple path.
174
223
match self_ty. sty {
175
224
ty:: Adt ( adt_def, substs) => {
176
- // FIXME(eddyb) always print without <> here.
177
- if substs. types ( ) . next ( ) . is_none ( ) { // ignore regions
178
- self . print_item_path ( adt_def. did )
179
- } else {
180
- self . path_impl ( & format ! ( "<{}>" , self_ty) )
181
- }
225
+ // FIXME(eddyb) this should recurse to build the path piecewise.
226
+ // self.print_item_path(adt_def.did, Some(substs), ns)
227
+ let mut s = String :: new ( ) ;
228
+ :: util:: ppaux:: parameterized ( & mut s, adt_def. did , substs, ns) . unwrap ( ) ;
229
+ self . path_impl ( & s)
182
230
}
183
231
184
- ty:: Foreign ( did) => self . print_item_path ( did) ,
232
+ ty:: Foreign ( did) => self . print_item_path ( did, None , ns ) ,
185
233
186
234
ty:: Bool |
187
235
ty:: Char |
@@ -262,11 +310,21 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
262
310
pub trait ItemPathPrinter : Sized {
263
311
type Path ;
264
312
265
- fn print_item_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , def_id : DefId ) -> Self :: Path {
266
- self . default_print_item_path ( def_id)
313
+ fn print_item_path (
314
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
315
+ def_id : DefId ,
316
+ substs : Option < & Substs < ' tcx > > ,
317
+ ns : Namespace ,
318
+ ) -> Self :: Path {
319
+ self . default_print_item_path ( def_id, substs, ns)
267
320
}
268
- fn print_impl_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , impl_def_id : DefId ) -> Self :: Path {
269
- self . default_print_impl_path ( impl_def_id)
321
+ fn print_impl_path (
322
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
323
+ impl_def_id : DefId ,
324
+ substs : Option < & Substs < ' tcx > > ,
325
+ ns : Namespace ,
326
+ ) -> Self :: Path {
327
+ self . default_print_impl_path ( impl_def_id, substs, ns)
270
328
}
271
329
272
330
fn path_crate ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , cnum : CrateNum ) -> Self :: Path ;
@@ -311,6 +369,7 @@ impl LocalPathPrinter {
311
369
fn try_print_visible_item_path (
312
370
self : & mut PrintCx < ' _ , ' _ , ' _ , Self > ,
313
371
def_id : DefId ,
372
+ ns : Namespace ,
314
373
) -> Option < <Self as ItemPathPrinter >:: Path > {
315
374
debug ! ( "try_print_visible_item_path: def_id={:?}" , def_id) ;
316
375
@@ -342,7 +401,7 @@ impl LocalPathPrinter {
342
401
} ) => {
343
402
debug ! ( "try_print_visible_item_path: def_id={:?}" , def_id) ;
344
403
let path = if !span. is_dummy ( ) {
345
- self . print_item_path ( def_id)
404
+ self . print_item_path ( def_id, None , ns )
346
405
} else {
347
406
self . path_crate ( cnum)
348
407
} ;
@@ -375,7 +434,7 @@ impl LocalPathPrinter {
375
434
}
376
435
377
436
let visible_parent = visible_parent_map. get ( & def_id) . cloned ( ) ?;
378
- let path = self . try_print_visible_item_path ( visible_parent) ?;
437
+ let path = self . try_print_visible_item_path ( visible_parent, ns ) ?;
379
438
let actual_parent = self . tcx . parent ( def_id) ;
380
439
381
440
let data = cur_def_key. disambiguated_data . data ;
@@ -446,11 +505,21 @@ impl LocalPathPrinter {
446
505
impl ItemPathPrinter for LocalPathPrinter {
447
506
type Path = String ;
448
507
449
- fn print_item_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , def_id : DefId ) -> Self :: Path {
450
- self . try_print_visible_item_path ( def_id)
451
- . unwrap_or_else ( || self . default_print_item_path ( def_id) )
508
+ fn print_item_path (
509
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
510
+ def_id : DefId ,
511
+ substs : Option < & Substs < ' tcx > > ,
512
+ ns : Namespace ,
513
+ ) -> Self :: Path {
514
+ self . try_print_visible_item_path ( def_id, ns)
515
+ . unwrap_or_else ( || self . default_print_item_path ( def_id, substs, ns) )
452
516
}
453
- fn print_impl_path ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , impl_def_id : DefId ) -> Self :: Path {
517
+ fn print_impl_path (
518
+ self : & mut PrintCx < ' _ , ' _ , ' tcx , Self > ,
519
+ impl_def_id : DefId ,
520
+ substs : Option < & Substs < ' tcx > > ,
521
+ ns : Namespace ,
522
+ ) -> Self :: Path {
454
523
// Always use types for non-local impls, where types are always
455
524
// available, and filename/line-number is mostly uninteresting.
456
525
let use_types = !impl_def_id. is_local ( ) || {
@@ -465,12 +534,12 @@ impl ItemPathPrinter for LocalPathPrinter {
465
534
// only occur very early in the compiler pipeline.
466
535
// FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
467
536
let parent_def_id = self . tcx . parent_def_id ( impl_def_id) . unwrap ( ) ;
468
- let path = self . print_item_path ( parent_def_id) ;
537
+ let path = self . print_item_path ( parent_def_id, None , ns ) ;
469
538
let span = self . tcx . def_span ( impl_def_id) ;
470
539
return self . path_append ( path, & format ! ( "<impl at {:?}>" , span) ) ;
471
540
}
472
541
473
- self . default_print_impl_path ( impl_def_id)
542
+ self . default_print_impl_path ( impl_def_id, substs , ns )
474
543
}
475
544
476
545
fn path_crate ( self : & mut PrintCx < ' _ , ' _ , ' _ , Self > , cnum : CrateNum ) -> Self :: Path {
0 commit comments