1- use hir:: map:: DefPathData ;
1+ use hir:: map:: { DefPathData , DisambiguatedDefPathData } ;
22use hir:: def_id:: { CrateNum , DefId } ;
33use ty:: { self , DefIdTree , Ty , TyCtxt } ;
4- use ty:: subst:: { Kind , Subst , Substs } ;
4+ use ty:: subst:: { Kind , Subst } ;
55
66use rustc_data_structures:: fx:: FxHashSet ;
77
@@ -29,14 +29,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
2929 fn print_def_path (
3030 self ,
3131 def_id : DefId ,
32- substs : Option < & ' tcx Substs < ' tcx > > ,
32+ substs : & ' tcx [ Kind < ' tcx > ] ,
3333 ) -> Result < Self :: Path , Self :: Error > {
3434 self . default_print_def_path ( def_id, substs)
3535 }
3636 fn print_impl_path (
3737 self ,
3838 impl_def_id : DefId ,
39- substs : Option < & ' tcx Substs < ' tcx > > ,
39+ substs : & ' tcx [ Kind < ' tcx > ] ,
4040 self_ty : Ty < ' tcx > ,
4141 trait_ref : Option < ty:: TraitRef < ' tcx > > ,
4242 ) -> Result < Self :: Path , Self :: Error > {
@@ -71,13 +71,14 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
7171 fn path_append_impl (
7272 self ,
7373 print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
74+ disambiguated_data : & DisambiguatedDefPathData ,
7475 self_ty : Ty < ' tcx > ,
7576 trait_ref : Option < ty:: TraitRef < ' tcx > > ,
7677 ) -> Result < Self :: Path , Self :: Error > ;
7778 fn path_append (
7879 self ,
7980 print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
80- text : & str ,
81+ disambiguated_data : & DisambiguatedDefPathData ,
8182 ) -> Result < Self :: Path , Self :: Error > ;
8283 fn path_generic_args (
8384 self ,
@@ -90,7 +91,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
9091 fn default_print_def_path (
9192 self ,
9293 def_id : DefId ,
93- substs : Option < & ' tcx Substs < ' tcx > > ,
94+ substs : & ' tcx [ Kind < ' tcx > ] ,
9495 ) -> Result < Self :: Path , Self :: Error > {
9596 debug ! ( "default_print_def_path: def_id={:?}, substs={:?}" , def_id, substs) ;
9697 let key = self . tcx ( ) . def_key ( def_id) ;
@@ -103,69 +104,69 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
103104 }
104105
105106 DefPathData :: Impl => {
107+ let generics = self . tcx ( ) . generics_of ( def_id) ;
106108 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-
111109 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) ;
113112 impl_trait_ref = impl_trait_ref. subst ( self . tcx ( ) , substs) ;
114113 }
115114 self . print_impl_path ( def_id, substs, self_ty, impl_trait_ref)
116115 }
117116
118117 _ => {
119- let generics = substs. map ( |_| self . tcx ( ) . generics_of ( def_id) ) ;
120- let generics_parent = generics. as_ref ( ) . and_then ( |g| g. parent ) ;
121118 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+
142126 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+ ) ;
151138 }
152139 }
153- } ;
154140
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 ;
160148 }
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+ )
161162 }
162163 }
163164 }
164165
165166 fn generic_args_to_print (
166167 & self ,
167168 generics : & ' tcx ty:: Generics ,
168- substs : & ' tcx Substs < ' tcx > ,
169+ substs : & ' tcx [ Kind < ' tcx > ] ,
169170 ) -> & ' tcx [ Kind < ' tcx > ] {
170171 let mut own_params = generics. parent_count ..generics. count ( ) ;
171172
@@ -192,19 +193,21 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
192193 fn default_print_impl_path (
193194 self ,
194195 impl_def_id : DefId ,
195- _substs : Option < & ' tcx Substs < ' tcx > > ,
196+ _substs : & ' tcx [ Kind < ' tcx > ] ,
196197 self_ty : Ty < ' tcx > ,
197198 impl_trait_ref : Option < ty:: TraitRef < ' tcx > > ,
198199 ) -> Result < Self :: Path , Self :: Error > {
199200 debug ! ( "default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}" ,
200201 impl_def_id, self_ty, impl_trait_ref) ;
201202
203+ let key = self . tcx ( ) . def_key ( impl_def_id) ;
204+ let parent_def_id = DefId { index : key. parent . unwrap ( ) , ..impl_def_id } ;
205+
202206 // Decide whether to print the parent path for the impl.
203207 // Logically, since impls are global, it's never needed, but
204208 // users may find it useful. Currently, we omit the parent if
205209 // the impl is either in the same module as the self-type or
206210 // as the trait.
207- let parent_def_id = self . tcx ( ) . parent ( impl_def_id) . unwrap ( ) ;
208211 let in_self_mod = match characteristic_def_id_of_type ( self_ty) {
209212 None => false ,
210213 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 {
219222 // trait-type, then fallback to a format that identifies
220223 // the module more clearly.
221224 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 ,
223227 self_ty,
224228 impl_trait_ref,
225229 )
0 commit comments