@@ -19,6 +19,7 @@ use ty::TyClosure;
19
19
use ty:: { TyBox , TyTrait , TyInt , TyUint , TyInfer } ;
20
20
use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
21
21
22
+ use std:: cell:: Cell ;
22
23
use std:: fmt;
23
24
use syntax:: abi:: Abi ;
24
25
use syntax:: parse:: token;
@@ -67,6 +68,45 @@ pub enum Ns {
67
68
Value
68
69
}
69
70
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
+
70
110
pub fn parameterized < GG > ( f : & mut fmt:: Formatter ,
71
111
substs : & subst:: Substs ,
72
112
did : DefId ,
@@ -80,8 +120,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
80
120
write ! ( f, "<{} as " , self_ty) ?;
81
121
}
82
122
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 {
85
125
// Try to get the impl/trait parent, if this is an
86
126
// associated value item (method or constant).
87
127
tcx. trait_of_item ( did) . or_else ( || tcx. impl_of_method ( did) )
@@ -90,97 +130,64 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
90
130
( did, None )
91
131
} ;
92
132
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 ) )
94
134
} ) ?;
95
135
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 {
125
137
let projection_ty = projections[ 0 ] . ty ;
126
138
if let TyTuple ( ref args) = substs. types . get_slice ( subst:: TypeSpace ) [ 0 ] . sty {
127
139
return fn_sig ( f, args, false , ty:: FnConverging ( projection_ty) ) ;
128
140
}
129
141
}
130
142
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)
141
148
} else {
142
- write ! ( f, "{}" , s ) ? ;
149
+ write ! ( f, "{}" , cont )
143
150
}
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) ?;
144
173
}
145
174
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
+
151
188
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
- } ) ;
182
189
183
- for & ty in & tps[ ..tps. len ( ) - num_defaults ] {
190
+ for & ty in & tps[ ..tps. len ( ) - num_supplied_defaults ] {
184
191
start_or_continue ( f, "<" , ", " ) ?;
185
192
write ! ( f, "{}" , ty) ?;
186
193
}
@@ -196,21 +203,28 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
196
203
197
204
// For values, also print their name and type parameters.
198
205
if ns == Ns :: Value {
206
+ empty. set ( true ) ;
207
+
199
208
if substs. self_ty ( ) . is_some ( ) {
200
209
write ! ( f, ">" ) ?;
201
210
}
202
211
203
- if let Some ( name ) = last_name {
204
- write ! ( f, "::{}" , name ) ?;
212
+ if let Some ( item_name ) = item_name {
213
+ write ! ( f, "::{}" , item_name ) ?;
205
214
}
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) ?;
213
225
}
226
+
227
+ start_or_continue ( f, "" , ">" ) ?;
214
228
}
215
229
216
230
Ok ( ( ) )
@@ -997,9 +1011,7 @@ impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
997
1011
998
1012
impl < ' tcx > fmt:: Display for ty:: TraitPredicate < ' tcx > {
999
1013
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)
1003
1015
}
1004
1016
}
1005
1017
0 commit comments