Skip to content

Commit a6fa7de

Browse files
authored
Rollup merge of #57865 - Aaron1011:fix/debug-ice, r=estebank
Don't ICE when logging unusual types MonoItemExt#to_string is used for both debug logging and LLVM symbol name generation. When debugging, we want to print out any type we encounter, even if it's something weird like GeneratorWitness. However, during codegen, we still want to error if we encounter an unexpected type when generating a name. To resolve this issue, this commit introduces a new 'debug' parameter to the relevant methods. When set to 'true', it allows any type to be printed - when set to 'false', it 'bug!'s when encountering an unexpected type. This prevents an ICE when enabling debug logging (via RUST_LOG) while running rustc on generator-related code.
2 parents a9950f6 + fc0c883 commit a6fa7de

File tree

5 files changed

+44
-30
lines changed

5 files changed

+44
-30
lines changed

src/librustc_codegen_llvm/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
5555
ty::Str => {
5656
let mut name = String::with_capacity(32);
5757
let printer = DefPathBasedNames::new(cx.tcx, true, true);
58-
printer.push_type_name(layout.ty, &mut name);
58+
printer.push_type_name(layout.ty, &mut name, false);
5959
if let (&ty::Adt(def, _), &layout::Variants::Single { index })
6060
= (&layout.ty.sty, &layout.variants)
6161
{

src/librustc_codegen_ssa/mono_item.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt;
1313
pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
1414
fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx) {
1515
debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}",
16-
self.to_string(cx.tcx()),
16+
self.to_string(cx.tcx(), true),
1717
self.to_raw_string(),
1818
cx.codegen_unit().name());
1919

@@ -45,7 +45,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
4545
}
4646

4747
debug!("END IMPLEMENTING '{} ({})' in cgu {}",
48-
self.to_string(cx.tcx()),
48+
self.to_string(cx.tcx(), true),
4949
self.to_raw_string(),
5050
cx.codegen_unit().name());
5151
}
@@ -57,7 +57,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
5757
visibility: Visibility
5858
) {
5959
debug!("BEGIN PREDEFINING '{} ({})' in cgu {}",
60-
self.to_string(cx.tcx()),
60+
self.to_string(cx.tcx(), true),
6161
self.to_raw_string(),
6262
cx.codegen_unit().name());
6363

@@ -76,7 +76,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
7676
}
7777

7878
debug!("END PREDEFINING '{} ({})' in cgu {}",
79-
self.to_string(cx.tcx()),
79+
self.to_string(cx.tcx(), true),
8080
self.to_raw_string(),
8181
cx.codegen_unit().name());
8282
}

src/librustc_mir/monomorphize/collector.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
355355
// We've been here already, no need to search again.
356356
return;
357357
}
358-
debug!("BEGIN collect_items_rec({})", starting_point.to_string(tcx));
358+
debug!("BEGIN collect_items_rec({})", starting_point.to_string(tcx, true));
359359

360360
let mut neighbors = Vec::new();
361361
let recursion_depth_reset;
@@ -409,7 +409,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
409409
recursion_depths.insert(def_id, depth);
410410
}
411411

412-
debug!("END collect_items_rec({})", starting_point.to_string(tcx));
412+
debug!("END collect_items_rec({})", starting_point.to_string(tcx, true));
413413
}
414414

415415
fn record_accesses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

src/librustc_mir/monomorphize/item.rs

+35-21
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
159159
tcx.substitute_normalize_and_test_predicates((def_id, &substs))
160160
}
161161

162-
fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
162+
fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, debug: bool) -> String {
163163
return match *self.as_mono_item() {
164164
MonoItem::Fn(instance) => {
165-
to_string_internal(tcx, "fn ", instance)
165+
to_string_internal(tcx, "fn ", instance, debug)
166166
},
167167
MonoItem::Static(def_id) => {
168168
let instance = Instance::new(def_id, tcx.intern_substs(&[]));
169-
to_string_internal(tcx, "static ", instance)
169+
to_string_internal(tcx, "static ", instance, debug)
170170
},
171171
MonoItem::GlobalAsm(..) => {
172172
"global_asm".to_string()
@@ -175,12 +175,13 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
175175

176176
fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
177177
prefix: &str,
178-
instance: Instance<'tcx>)
178+
instance: Instance<'tcx>,
179+
debug: bool)
179180
-> String {
180181
let mut result = String::with_capacity(32);
181182
result.push_str(prefix);
182183
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);
184185
result
185186
}
186187
}
@@ -238,7 +239,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
238239
}
239240
}
240241

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) {
242249
match t.sty {
243250
ty::Bool => output.push_str("bool"),
244251
ty::Char => output.push_str("char"),
@@ -260,12 +267,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
260267
ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
261268
ty::Adt(adt_def, substs) => {
262269
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);
264271
},
265272
ty::Tuple(component_types) => {
266273
output.push('(');
267274
for &component_type in component_types {
268-
self.push_type_name(component_type, output);
275+
self.push_type_name(component_type, output, debug);
269276
output.push_str(", ");
270277
}
271278
if !component_types.is_empty() {
@@ -281,25 +288,25 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
281288
hir::MutMutable => output.push_str("mut "),
282289
}
283290

284-
self.push_type_name(inner_type, output);
291+
self.push_type_name(inner_type, output, debug);
285292
},
286293
ty::Ref(_, inner_type, mutbl) => {
287294
output.push('&');
288295
if mutbl == hir::MutMutable {
289296
output.push_str("mut ");
290297
}
291298

292-
self.push_type_name(inner_type, output);
299+
self.push_type_name(inner_type, output, debug);
293300
},
294301
ty::Array(inner_type, len) => {
295302
output.push('[');
296-
self.push_type_name(inner_type, output);
303+
self.push_type_name(inner_type, output, debug);
297304
write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap();
298305
output.push(']');
299306
},
300307
ty::Slice(inner_type) => {
301308
output.push('[');
302-
self.push_type_name(inner_type, output);
309+
self.push_type_name(inner_type, output, debug);
303310
output.push(']');
304311
},
305312
ty::Dynamic(ref trait_data, ..) => {
@@ -309,6 +316,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
309316
principal.skip_binder().substs,
310317
trait_data.projection_bounds(),
311318
output,
319+
debug
312320
);
313321
} else {
314322
output.push_str("dyn '_");
@@ -338,7 +346,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
338346

339347
if !sig.inputs().is_empty() {
340348
for &parameter_type in sig.inputs() {
341-
self.push_type_name(parameter_type, output);
349+
self.push_type_name(parameter_type, output, debug);
342350
output.push_str(", ");
343351
}
344352
output.pop();
@@ -357,15 +365,15 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
357365

358366
if !sig.output().is_unit() {
359367
output.push_str(" -> ");
360-
self.push_type_name(sig.output(), output);
368+
self.push_type_name(sig.output(), output, debug);
361369
}
362370
},
363371
ty::Generator(def_id, GeneratorSubsts { ref substs }, _) |
364372
ty::Closure(def_id, ClosureSubsts { ref substs }) => {
365373
self.push_def_path(def_id, output);
366374
let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
367375
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);
369377
}
370378
ty::Error |
371379
ty::Bound(..) |
@@ -376,8 +384,12 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
376384
ty::Param(_) |
377385
ty::GeneratorWitness(_) |
378386
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 \
380391
unexpected type: {:?}", t);
392+
}
381393
}
382394
}
383395
}
@@ -412,7 +424,8 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
412424
fn push_type_params<I>(&self,
413425
substs: &Substs<'tcx>,
414426
projections: I,
415-
output: &mut String)
427+
output: &mut String,
428+
debug: bool)
416429
where I: Iterator<Item=ty::PolyExistentialProjection<'tcx>>
417430
{
418431
let mut projections = projections.peekable();
@@ -423,7 +436,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
423436
output.push('<');
424437

425438
for type_parameter in substs.types() {
426-
self.push_type_name(type_parameter, output);
439+
self.push_type_name(type_parameter, output, debug);
427440
output.push_str(", ");
428441
}
429442

@@ -432,7 +445,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
432445
let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str();
433446
output.push_str(name);
434447
output.push_str("=");
435-
self.push_type_name(projection.ty, output);
448+
self.push_type_name(projection.ty, output, debug);
436449
output.push_str(", ");
437450
}
438451

@@ -444,8 +457,9 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
444457

445458
pub fn push_instance_as_string(&self,
446459
instance: Instance<'tcx>,
447-
output: &mut String) {
460+
output: &mut String,
461+
debug: bool) {
448462
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);
450464
}
451465
}

src/librustc_mir/monomorphize/partitioning.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
879879
.unwrap_or("<no hash>");
880880

881881
debug!(" - {} [{:?}] [{}]",
882-
mono_item.to_string(tcx),
882+
mono_item.to_string(tcx, true),
883883
linkage,
884884
symbol_hash);
885885
}
@@ -971,7 +971,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>(
971971
let mut item_keys: Vec<_> = items
972972
.iter()
973973
.map(|i| {
974-
let mut output = i.to_string(tcx);
974+
let mut output = i.to_string(tcx, false);
975975
output.push_str(" @@");
976976
let mut empty = Vec::new();
977977
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);

0 commit comments

Comments
 (0)