@@ -159,14 +159,14 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
159
159
tcx.substitute_normalize_and_test_predicates((def_id, &substs))
160
160
}
161
161
162
- fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
162
+ fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, debug: bool ) -> String {
163
163
return match *self.as_mono_item() {
164
164
MonoItem::Fn(instance) => {
165
- to_string_internal(tcx, "fn ", instance)
165
+ to_string_internal(tcx, "fn ", instance, debug )
166
166
},
167
167
MonoItem::Static(def_id) => {
168
168
let instance = Instance::new(def_id, tcx.intern_substs(&[]));
169
- to_string_internal(tcx, "static ", instance)
169
+ to_string_internal(tcx, "static ", instance, debug )
170
170
},
171
171
MonoItem::GlobalAsm(..) => {
172
172
"global_asm".to_string()
@@ -175,12 +175,13 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
175
175
176
176
fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
177
177
prefix: &str,
178
- instance: Instance<'tcx>)
178
+ instance: Instance<'tcx>,
179
+ debug: bool)
179
180
-> String {
180
181
let mut result = String::with_capacity(32);
181
182
result.push_str(prefix);
182
183
let printer = DefPathBasedNames::new(tcx, false, false);
183
- printer.push_instance_as_string(instance, &mut result);
184
+ printer.push_instance_as_string(instance, &mut result, debug );
184
185
result
185
186
}
186
187
}
@@ -238,7 +239,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
238
239
}
239
240
}
240
241
241
- pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
242
+ // Pushes the type name of the specified type to the provided string.
243
+ // If 'debug' is true, printing normally unprintable types is allowed
244
+ // (e.g. ty::GeneratorWitness). This parameter should only be set when
245
+ // this method is being used for logging purposes (e.g. with debug! or info!)
246
+ // When being used for codegen purposes, 'debug' should be set to 'false'
247
+ // in order to catch unexpected types that should never end up in a type name
248
+ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
242
249
match t.sty {
243
250
ty::Bool => output.push_str("bool"),
244
251
ty::Char => output.push_str("char"),
@@ -260,12 +267,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
260
267
ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
261
268
ty::Adt(adt_def, substs) => {
262
269
self.push_def_path(adt_def.did, output);
263
- self.push_type_params(substs, iter::empty(), output);
270
+ self.push_type_params(substs, iter::empty(), output, debug );
264
271
},
265
272
ty::Tuple(component_types) => {
266
273
output.push('(');
267
274
for &component_type in component_types {
268
- self.push_type_name(component_type, output);
275
+ self.push_type_name(component_type, output, debug );
269
276
output.push_str(", ");
270
277
}
271
278
if !component_types.is_empty() {
@@ -281,25 +288,25 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
281
288
hir::MutMutable => output.push_str("mut "),
282
289
}
283
290
284
- self.push_type_name(inner_type, output);
291
+ self.push_type_name(inner_type, output, debug );
285
292
},
286
293
ty::Ref(_, inner_type, mutbl) => {
287
294
output.push('&');
288
295
if mutbl == hir::MutMutable {
289
296
output.push_str("mut ");
290
297
}
291
298
292
- self.push_type_name(inner_type, output);
299
+ self.push_type_name(inner_type, output, debug );
293
300
},
294
301
ty::Array(inner_type, len) => {
295
302
output.push('[');
296
- self.push_type_name(inner_type, output);
303
+ self.push_type_name(inner_type, output, debug );
297
304
write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap();
298
305
output.push(']');
299
306
},
300
307
ty::Slice(inner_type) => {
301
308
output.push('[');
302
- self.push_type_name(inner_type, output);
309
+ self.push_type_name(inner_type, output, debug );
303
310
output.push(']');
304
311
},
305
312
ty::Dynamic(ref trait_data, ..) => {
@@ -309,6 +316,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
309
316
principal.skip_binder().substs,
310
317
trait_data.projection_bounds(),
311
318
output,
319
+ debug
312
320
);
313
321
} else {
314
322
output.push_str("dyn '_");
@@ -338,7 +346,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
338
346
339
347
if !sig.inputs().is_empty() {
340
348
for ¶meter_type in sig.inputs() {
341
- self.push_type_name(parameter_type, output);
349
+ self.push_type_name(parameter_type, output, debug );
342
350
output.push_str(", ");
343
351
}
344
352
output.pop();
@@ -357,15 +365,15 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
357
365
358
366
if !sig.output().is_unit() {
359
367
output.push_str(" -> ");
360
- self.push_type_name(sig.output(), output);
368
+ self.push_type_name(sig.output(), output, debug );
361
369
}
362
370
},
363
371
ty::Generator(def_id, GeneratorSubsts { ref substs }, _) |
364
372
ty::Closure(def_id, ClosureSubsts { ref substs }) => {
365
373
self.push_def_path(def_id, output);
366
374
let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
367
375
let substs = substs.truncate_to(self.tcx, generics);
368
- self.push_type_params(substs, iter::empty(), output);
376
+ self.push_type_params(substs, iter::empty(), output, debug );
369
377
}
370
378
ty::Error |
371
379
ty::Bound(..) |
@@ -376,8 +384,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
376
384
ty::Param(_) |
377
385
ty::GeneratorWitness(_) |
378
386
ty::Opaque(..) => {
379
- bug!("DefPathBasedNames: Trying to create type name for \
387
+ if debug {
388
+ output.push_str(&format!("`{:?}`", t));
389
+ } else {
390
+ bug!("DefPathBasedNames: Trying to create type name for \
380
391
unexpected type: {:?}", t);
392
+ }
381
393
}
382
394
}
383
395
}
@@ -412,7 +424,8 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
412
424
fn push_type_params<I>(&self,
413
425
substs: &Substs<'tcx>,
414
426
projections: I,
415
- output: &mut String)
427
+ output: &mut String,
428
+ debug: bool)
416
429
where I: Iterator<Item=ty::PolyExistentialProjection<'tcx>>
417
430
{
418
431
let mut projections = projections.peekable();
@@ -423,7 +436,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
423
436
output.push('<');
424
437
425
438
for type_parameter in substs.types() {
426
- self.push_type_name(type_parameter, output);
439
+ self.push_type_name(type_parameter, output, debug );
427
440
output.push_str(", ");
428
441
}
429
442
@@ -432,7 +445,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
432
445
let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str();
433
446
output.push_str(name);
434
447
output.push_str("=");
435
- self.push_type_name(projection.ty, output);
448
+ self.push_type_name(projection.ty, output, debug );
436
449
output.push_str(", ");
437
450
}
438
451
@@ -444,8 +457,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
444
457
445
458
pub fn push_instance_as_string(&self,
446
459
instance: Instance<'tcx>,
447
- output: &mut String) {
460
+ output: &mut String,
461
+ debug: bool) {
448
462
self.push_def_path(instance.def_id(), output);
449
- self.push_type_params(instance.substs, iter::empty(), output);
463
+ self.push_type_params(instance.substs, iter::empty(), output, debug );
450
464
}
451
465
}
0 commit comments