1
- use hir:: map:: DefPathData ;
1
+ use hir:: map:: { DefPathData , DisambiguatedDefPathData } ;
2
2
use hir:: def_id:: { CrateNum , DefId } ;
3
3
use ty:: { self , DefIdTree , Ty , TyCtxt } ;
4
- use ty:: subst:: { Kind , Subst , Substs } ;
4
+ use ty:: subst:: { Kind , Subst } ;
5
5
6
6
use rustc_data_structures:: fx:: FxHashSet ;
7
7
@@ -29,14 +29,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
29
29
fn print_def_path (
30
30
self ,
31
31
def_id : DefId ,
32
- substs : Option < & ' tcx Substs < ' tcx > > ,
32
+ substs : & ' tcx [ Kind < ' tcx > ] ,
33
33
) -> Result < Self :: Path , Self :: Error > {
34
34
self . default_print_def_path ( def_id, substs)
35
35
}
36
36
fn print_impl_path (
37
37
self ,
38
38
impl_def_id : DefId ,
39
- substs : Option < & ' tcx Substs < ' tcx > > ,
39
+ substs : & ' tcx [ Kind < ' tcx > ] ,
40
40
self_ty : Ty < ' tcx > ,
41
41
trait_ref : Option < ty:: TraitRef < ' tcx > > ,
42
42
) -> Result < Self :: Path , Self :: Error > {
@@ -71,13 +71,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
71
71
fn path_append_impl (
72
72
self ,
73
73
print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
74
+ disambiguated_data : & DisambiguatedDefPathData ,
74
75
self_ty : Ty < ' tcx > ,
75
76
trait_ref : Option < ty:: TraitRef < ' tcx > > ,
76
77
) -> Result < Self :: Path , Self :: Error > ;
77
78
fn path_append (
78
79
self ,
79
80
print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
80
- text : & str ,
81
+ disambiguated_data : & DisambiguatedDefPathData ,
81
82
) -> Result < Self :: Path , Self :: Error > ;
82
83
fn path_generic_args (
83
84
self ,
@@ -90,7 +91,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
90
91
fn default_print_def_path (
91
92
self ,
92
93
def_id : DefId ,
93
- substs : Option < & ' tcx Substs < ' tcx > > ,
94
+ substs : & ' tcx [ Kind < ' tcx > ] ,
94
95
) -> Result < Self :: Path , Self :: Error > {
95
96
debug ! ( "default_print_def_path: def_id={:?}, substs={:?}" , def_id, substs) ;
96
97
let key = self . tcx ( ) . def_key ( def_id) ;
@@ -103,69 +104,69 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
103
104
}
104
105
105
106
DefPathData :: Impl => {
107
+ let generics = self . tcx ( ) . generics_of ( def_id) ;
106
108
let mut self_ty = self . tcx ( ) . type_of ( def_id) ;
107
- if let Some ( substs) = substs {
108
- self_ty = self_ty. subst ( self . tcx ( ) , substs) ;
109
- }
110
-
111
109
let mut impl_trait_ref = self . tcx ( ) . impl_trait_ref ( def_id) ;
112
- if let Some ( substs) = substs {
110
+ if substs. len ( ) >= generics. count ( ) {
111
+ self_ty = self_ty. subst ( self . tcx ( ) , substs) ;
113
112
impl_trait_ref = impl_trait_ref. subst ( self . tcx ( ) , substs) ;
114
113
}
115
114
self . print_impl_path ( def_id, substs, self_ty, impl_trait_ref)
116
115
}
117
116
118
117
_ => {
119
- let generics = substs. map ( |_| self . tcx ( ) . generics_of ( def_id) ) ;
120
- let generics_parent = generics. as_ref ( ) . and_then ( |g| g. parent ) ;
121
118
let parent_def_id = DefId { index : key. parent . unwrap ( ) , ..def_id } ;
122
- let print_parent_path = |cx : Self | {
123
- if let Some ( generics_parent_def_id) = generics_parent {
124
- assert_eq ! ( parent_def_id, generics_parent_def_id) ;
125
-
126
- // FIXME(eddyb) try to move this into the parent's printing
127
- // logic, instead of doing it when printing the child.
128
- let parent_generics = cx. tcx ( ) . generics_of ( parent_def_id) ;
129
- let parent_has_own_self =
130
- parent_generics. has_self && parent_generics. parent_count == 0 ;
131
- if let ( Some ( substs) , true ) = ( substs, parent_has_own_self) {
132
- let trait_ref = ty:: TraitRef :: new ( parent_def_id, substs) ;
133
- cx. path_qualified ( trait_ref. self_ty ( ) , Some ( trait_ref) )
134
- } else {
135
- cx. print_def_path ( parent_def_id, substs)
136
- }
137
- } else {
138
- cx. print_def_path ( parent_def_id, None )
139
- }
140
- } ;
141
- let print_path = |cx : Self | {
119
+
120
+ let mut parent_substs = substs;
121
+ let mut trait_qualify_parent = false ;
122
+ if !substs. is_empty ( ) {
123
+ let generics = self . tcx ( ) . generics_of ( def_id) ;
124
+ parent_substs = & substs[ ..generics. parent_count . min ( substs. len ( ) ) ] ;
125
+
142
126
match key. disambiguated_data . data {
143
- // Skip `::{{constructor}}` on tuple/unit structs.
144
- DefPathData :: StructCtor => print_parent_path ( cx) ,
145
-
146
- _ => {
147
- cx. path_append (
148
- print_parent_path,
149
- & key. disambiguated_data . data . as_interned_str ( ) . as_str ( ) ,
150
- )
127
+ // Closures' own generics are only captures, don't print them.
128
+ DefPathData :: ClosureExpr => { }
129
+
130
+ // If we have any generic arguments to print, we do that
131
+ // on top of the same path, but without its own generics.
132
+ _ => if !generics. params . is_empty ( ) && substs. len ( ) >= generics. count ( ) {
133
+ let args = self . generic_args_to_print ( generics, substs) ;
134
+ return self . path_generic_args (
135
+ |cx| cx. print_def_path ( def_id, parent_substs) ,
136
+ args,
137
+ ) ;
151
138
}
152
139
}
153
- } ;
154
140
155
- if let ( Some ( generics) , Some ( substs) ) = ( generics, substs) {
156
- let args = self . generic_args_to_print ( generics, substs) ;
157
- self . path_generic_args ( print_path, args)
158
- } else {
159
- print_path ( self )
141
+ // FIXME(eddyb) try to move this into the parent's printing
142
+ // logic, instead of doing it when printing the child.
143
+ trait_qualify_parent =
144
+ generics. has_self &&
145
+ generics. parent == Some ( parent_def_id) &&
146
+ parent_substs. len ( ) == generics. parent_count &&
147
+ self . tcx ( ) . generics_of ( parent_def_id) . parent_count == 0 ;
160
148
}
149
+
150
+ self . path_append (
151
+ |cx : Self | if trait_qualify_parent {
152
+ let trait_ref = ty:: TraitRef :: new (
153
+ parent_def_id,
154
+ cx. tcx ( ) . intern_substs ( parent_substs) ,
155
+ ) ;
156
+ cx. path_qualified ( trait_ref. self_ty ( ) , Some ( trait_ref) )
157
+ } else {
158
+ cx. print_def_path ( parent_def_id, parent_substs)
159
+ } ,
160
+ & key. disambiguated_data ,
161
+ )
161
162
}
162
163
}
163
164
}
164
165
165
166
fn generic_args_to_print (
166
167
& self ,
167
168
generics : & ' tcx ty:: Generics ,
168
- substs : & ' tcx Substs < ' tcx > ,
169
+ substs : & ' tcx [ Kind < ' tcx > ] ,
169
170
) -> & ' tcx [ Kind < ' tcx > ] {
170
171
let mut own_params = generics. parent_count ..generics. count ( ) ;
171
172
@@ -192,19 +193,21 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
192
193
fn default_print_impl_path (
193
194
self ,
194
195
impl_def_id : DefId ,
195
- _substs : Option < & ' tcx Substs < ' tcx > > ,
196
+ _substs : & ' tcx [ Kind < ' tcx > ] ,
196
197
self_ty : Ty < ' tcx > ,
197
198
impl_trait_ref : Option < ty:: TraitRef < ' tcx > > ,
198
199
) -> Result < Self :: Path , Self :: Error > {
199
200
debug ! ( "default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}" ,
200
201
impl_def_id, self_ty, impl_trait_ref) ;
201
202
203
+ let key = self . tcx ( ) . def_key ( impl_def_id) ;
204
+ let parent_def_id = DefId { index : key. parent . unwrap ( ) , ..impl_def_id } ;
205
+
202
206
// Decide whether to print the parent path for the impl.
203
207
// Logically, since impls are global, it's never needed, but
204
208
// users may find it useful. Currently, we omit the parent if
205
209
// the impl is either in the same module as the self-type or
206
210
// as the trait.
207
- let parent_def_id = self . tcx ( ) . parent ( impl_def_id) . unwrap ( ) ;
208
211
let in_self_mod = match characteristic_def_id_of_type ( self_ty) {
209
212
None => false ,
210
213
Some ( ty_def_id) => self . tcx ( ) . parent ( ty_def_id) == Some ( parent_def_id) ,
@@ -219,7 +222,8 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
219
222
// trait-type, then fallback to a format that identifies
220
223
// the module more clearly.
221
224
self . path_append_impl (
222
- |cx| cx. print_def_path ( parent_def_id, None ) ,
225
+ |cx| cx. print_def_path ( parent_def_id, & [ ] ) ,
226
+ & key. disambiguated_data ,
223
227
self_ty,
224
228
impl_trait_ref,
225
229
)
0 commit comments