@@ -19,6 +19,7 @@ use ty::TyClosure;
1919use ty:: { TyBox , TyTrait , TyInt , TyUint , TyInfer } ;
2020use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
2121
22+ use std:: cell:: Cell ;
2223use std:: fmt;
2324use syntax:: abi:: Abi ;
2425use syntax:: parse:: token;
@@ -67,6 +68,45 @@ pub enum Ns {
6768 Value
6869}
6970
71+ fn number_of_supplied_defaults < ' tcx , GG > ( tcx : & ty:: TyCtxt < ' tcx > ,
72+ substs : & subst:: Substs ,
73+ space : subst:: ParamSpace ,
74+ get_generics : GG )
75+ -> usize
76+ where GG : FnOnce ( & TyCtxt < ' tcx > ) -> ty:: Generics < ' tcx >
77+ {
78+ let generics = get_generics ( tcx) ;
79+
80+ let has_self = substs. self_ty ( ) . is_some ( ) ;
81+ let ty_params = generics. types . get_slice ( space) ;
82+ let tps = substs. types . get_slice ( space) ;
83+ if ty_params. last ( ) . map_or ( false , |def| def. default . is_some ( ) ) {
84+ let substs = tcx. lift ( & substs) ;
85+ ty_params. iter ( ) . zip ( tps) . rev ( ) . take_while ( |& ( def, & actual) | {
86+ match def. default {
87+ Some ( default) => {
88+ if !has_self && default. has_self_ty ( ) {
89+ // In an object type, there is no `Self`, and
90+ // thus if the default value references Self,
91+ // the user will be required to give an
92+ // explicit value. We can't even do the
93+ // substitution below to check without causing
94+ // an ICE. (#18956).
95+ false
96+ } else {
97+ let default = tcx. lift ( & default) ;
98+ substs. and_then ( |substs| default. subst ( tcx, substs) )
99+ == Some ( actual)
100+ }
101+ }
102+ None => false
103+ }
104+ } ) . count ( )
105+ } else {
106+ 0
107+ }
108+ }
109+
70110pub fn parameterized < GG > ( f : & mut fmt:: Formatter ,
71111 substs : & subst:: Substs ,
72112 did : DefId ,
@@ -80,8 +120,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
80120 write ! ( f, "<{} as " , self_ty) ?;
81121 }
82122
83- let ( fn_trait_kind, verbose, last_name ) = ty:: tls:: with ( |tcx| {
84- let ( did, last_name ) = if ns == Ns :: Value {
123+ let ( fn_trait_kind, verbose, item_name ) = ty:: tls:: with ( |tcx| {
124+ let ( did, item_name ) = if ns == Ns :: Value {
85125 // Try to get the impl/trait parent, if this is an
86126 // associated value item (method or constant).
87127 tcx. trait_of_item ( did) . or_else ( || tcx. impl_of_method ( did) )
@@ -90,97 +130,64 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
90130 ( did, None )
91131 } ;
92132 write ! ( f, "{}" , tcx. item_path_str( did) ) ?;
93- Ok ( ( tcx. lang_items . fn_trait_kind ( did) , tcx. sess . verbose ( ) , last_name ) )
133+ Ok ( ( tcx. lang_items . fn_trait_kind ( did) , tcx. sess . verbose ( ) , item_name ) )
94134 } ) ?;
95135
96- let mut empty = true ;
97- let mut start_or_continue = |f : & mut fmt:: Formatter , start : & str , cont : & str | {
98- if empty {
99- empty = false ;
100- write ! ( f, "{}" , start)
101- } else {
102- write ! ( f, "{}" , cont)
103- }
104- } ;
105-
106- if verbose {
107- for region in & substs. regions {
108- start_or_continue ( f, "<" , ", " ) ?;
109- write ! ( f, "{:?}" , region) ?;
110- }
111- for & ty in & substs. types {
112- start_or_continue ( f, "<" , ", " ) ?;
113- write ! ( f, "{}" , ty) ?;
114- }
115- for projection in projections {
116- start_or_continue ( f, "<" , ", " ) ?;
117- write ! ( f, "{}={}" ,
118- projection. projection_ty. item_name,
119- projection. ty) ?;
120- }
121- return start_or_continue ( f, "" , ">" ) ;
122- }
123-
124- if fn_trait_kind. is_some ( ) && projections. len ( ) == 1 {
136+ if !verbose && fn_trait_kind. is_some ( ) && projections. len ( ) == 1 {
125137 let projection_ty = projections[ 0 ] . ty ;
126138 if let TyTuple ( ref args) = substs. types . get_slice ( subst:: TypeSpace ) [ 0 ] . sty {
127139 return fn_sig ( f, args, false , ty:: FnConverging ( projection_ty) ) ;
128140 }
129141 }
130142
131- for & r in & substs. regions {
132- start_or_continue ( f, "<" , ", " ) ?;
133- let s = r. to_string ( ) ;
134- if s. is_empty ( ) {
135- // This happens when the value of the region
136- // parameter is not easily serialized. This may be
137- // because the user omitted it in the first place,
138- // or because it refers to some block in the code,
139- // etc. I'm not sure how best to serialize this.
140- write ! ( f, "'_" ) ?;
143+ let empty = Cell :: new ( true ) ;
144+ let start_or_continue = |f : & mut fmt:: Formatter , start : & str , cont : & str | {
145+ if empty. get ( ) {
146+ empty. set ( false ) ;
147+ write ! ( f, "{}" , start)
141148 } else {
142- write ! ( f, "{}" , s ) ? ;
149+ write ! ( f, "{}" , cont )
143150 }
151+ } ;
152+ let print_region = |f : & mut fmt:: Formatter , region : & ty:: Region | -> _ {
153+ if verbose {
154+ write ! ( f, "{:?}" , region)
155+ } else {
156+ let s = region. to_string ( ) ;
157+ if s. is_empty ( ) {
158+ // This happens when the value of the region
159+ // parameter is not easily serialized. This may be
160+ // because the user omitted it in the first place,
161+ // or because it refers to some block in the code,
162+ // etc. I'm not sure how best to serialize this.
163+ write ! ( f, "'_" )
164+ } else {
165+ write ! ( f, "{}" , s)
166+ }
167+ }
168+ } ;
169+
170+ for region in substs. regions . get_slice ( subst:: TypeSpace ) {
171+ start_or_continue ( f, "<" , ", " ) ?;
172+ print_region ( f, region) ?;
144173 }
145174
146- // It is important to execute this conditionally, only if -Z
147- // verbose is false. Otherwise, debug logs can sometimes cause
148- // ICEs trying to fetch the generics early in the pipeline. This
149- // is kind of a hacky workaround in that -Z verbose is required to
150- // avoid those ICEs.
175+ let num_supplied_defaults = if verbose {
176+ 0
177+ } else {
178+ // It is important to execute this conditionally, only if -Z
179+ // verbose is false. Otherwise, debug logs can sometimes cause
180+ // ICEs trying to fetch the generics early in the pipeline. This
181+ // is kind of a hacky workaround in that -Z verbose is required to
182+ // avoid those ICEs.
183+ ty:: tls:: with ( |tcx| {
184+ number_of_supplied_defaults ( tcx, substs, subst:: TypeSpace , get_generics)
185+ } )
186+ } ;
187+
151188 let tps = substs. types . get_slice ( subst:: TypeSpace ) ;
152- let num_defaults = ty:: tls:: with ( |tcx| {
153- let generics = get_generics ( tcx) ;
154-
155- let has_self = substs. self_ty ( ) . is_some ( ) ;
156- let ty_params = generics. types . get_slice ( subst:: TypeSpace ) ;
157- if ty_params. last ( ) . map_or ( false , |def| def. default . is_some ( ) ) {
158- let substs = tcx. lift ( & substs) ;
159- ty_params. iter ( ) . zip ( tps) . rev ( ) . take_while ( |& ( def, & actual) | {
160- match def. default {
161- Some ( default) => {
162- if !has_self && default. has_self_ty ( ) {
163- // In an object type, there is no `Self`, and
164- // thus if the default value references Self,
165- // the user will be required to give an
166- // explicit value. We can't even do the
167- // substitution below to check without causing
168- // an ICE. (#18956).
169- false
170- } else {
171- let default = tcx. lift ( & default) ;
172- substs. and_then ( |substs| default. subst ( tcx, substs) ) == Some ( actual)
173- }
174- }
175- None => false
176- }
177- } ) . count ( )
178- } else {
179- 0
180- }
181- } ) ;
182189
183- for & ty in & tps[ ..tps. len ( ) - num_defaults ] {
190+ for & ty in & tps[ ..tps. len ( ) - num_supplied_defaults ] {
184191 start_or_continue ( f, "<" , ", " ) ?;
185192 write ! ( f, "{}" , ty) ?;
186193 }
@@ -196,21 +203,28 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
196203
197204 // For values, also print their name and type parameters.
198205 if ns == Ns :: Value {
206+ empty. set ( true ) ;
207+
199208 if substs. self_ty ( ) . is_some ( ) {
200209 write ! ( f, ">" ) ?;
201210 }
202211
203- if let Some ( name ) = last_name {
204- write ! ( f, "::{}" , name ) ?;
212+ if let Some ( item_name ) = item_name {
213+ write ! ( f, "::{}" , item_name ) ?;
205214 }
206- let tps = substs. types . get_slice ( subst:: FnSpace ) ;
207- if !tps. is_empty ( ) {
208- write ! ( f, "::<{}" , tps[ 0 ] ) ?;
209- for ty in & tps[ 1 ..] {
210- write ! ( f, ", {}" , ty) ?;
211- }
212- write ! ( f, ">" ) ?;
215+
216+ for region in substs. regions . get_slice ( subst:: FnSpace ) {
217+ start_or_continue ( f, "::<" , ", " ) ?;
218+ print_region ( f, region) ?;
219+ }
220+
221+ // FIXME: consider being smart with defaults here too
222+ for ty in substs. types . get_slice ( subst:: FnSpace ) {
223+ start_or_continue ( f, "::<" , ", " ) ?;
224+ write ! ( f, "{}" , ty) ?;
213225 }
226+
227+ start_or_continue ( f, "" , ">" ) ?;
214228 }
215229
216230 Ok ( ( ) )
@@ -997,9 +1011,7 @@ impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
9971011
9981012impl < ' tcx > fmt:: Display for ty:: TraitPredicate < ' tcx > {
9991013 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1000- write ! ( f, "{} : {}" ,
1001- self . trait_ref. self_ty( ) ,
1002- self . trait_ref)
1014+ write ! ( f, "{}: {}" , self . trait_ref. self_ty( ) , self . trait_ref)
10031015 }
10041016}
10051017
0 commit comments