Skip to content

Commit 8579266

Browse files
committed
Debug print the problematic type to help debugging
1 parent 1fa0971 commit 8579266

17 files changed

Lines changed: 122 additions & 47 deletions

File tree

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,14 +422,15 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
422422
source_info.span,
423423
)
424424
}
425-
AssertKind::InvalidEnumConstruction(source) => {
425+
AssertKind::InvalidEnumConstruction(ty, source) => {
426+
let ty = codegen_operand(fx, ty).load_scalar(fx);
426427
let source = codegen_operand(fx, source).load_scalar(fx);
427428
let location = fx.get_caller_location(source_info).load_scalar(fx);
428429

429430
codegen_panic_inner(
430431
fx,
431432
rustc_hir::LangItem::PanicInvalidEnumConstruction,
432-
&[source, location],
433+
&[ty, source, location],
433434
*unwind,
434435
source_info.span,
435436
)

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
2424
use crate::base::{self, is_call_from_compiler_builtins_to_upstream_monomorphization};
2525
use crate::common::{self, IntPredicate};
2626
use crate::errors::CompilerBuiltinsCannotCall;
27+
use crate::mir::operand::OperandValue;
2728
use crate::traits::*;
2829
use crate::{MemFlags, meth};
2930

@@ -761,11 +762,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
761762
// `#[track_caller]` adds an implicit argument.
762763
(LangItem::PanicNullPointerDereference, vec![location])
763764
}
764-
AssertKind::InvalidEnumConstruction(source) => {
765+
AssertKind::InvalidEnumConstruction(ty, source) => {
765766
let source = self.codegen_operand(bx, source).immediate();
767+
let OperandValue::Pair(ptr, len) = self.codegen_operand(bx, ty).val else {
768+
panic!("What the hell?");
769+
};
770+
let ptr = ptr;
771+
let len = len;
766772
// It's `fn panic_invalid_enum_construction(source: u128)`,
767773
// `#[track_caller]` adds an implicit argument.
768-
(LangItem::PanicInvalidEnumConstruction, vec![source, location])
774+
(LangItem::PanicInvalidEnumConstruction, vec![ptr, len, source, location])
769775
}
770776
_ => {
771777
// It's `pub fn panic_...()` and `#[track_caller]` adds an implicit argument.

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
652652
found: eval_to_int(found)?,
653653
},
654654
NullPointerDereference => NullPointerDereference,
655-
InvalidEnumConstruction(source) => InvalidEnumConstruction(eval_to_int(source)?),
655+
InvalidEnumConstruction(ty, source) => {
656+
InvalidEnumConstruction(eval_to_int(ty)?, eval_to_int(source)?)
657+
}
656658
};
657659
Err(ConstEvalErrKind::AssertFailure(err)).into()
658660
}

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ pub enum AssertKind<O> {
10741074
ResumedAfterDrop(CoroutineKind),
10751075
MisalignedPointerDereference { required: O, found: O },
10761076
NullPointerDereference,
1077-
InvalidEnumConstruction(O),
1077+
InvalidEnumConstruction(O, O),
10781078
}
10791079

10801080
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl<O> AssertKind<O> {
208208
LangItem::PanicGenFnNonePanic
209209
}
210210
NullPointerDereference => LangItem::PanicNullPointerDereference,
211-
InvalidEnumConstruction(_) => LangItem::PanicInvalidEnumConstruction,
211+
InvalidEnumConstruction(..) => LangItem::PanicInvalidEnumConstruction,
212212
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedDrop,
213213
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
214214
LangItem::PanicAsyncFnResumedDrop
@@ -285,8 +285,11 @@ impl<O> AssertKind<O> {
285285
)
286286
}
287287
NullPointerDereference => write!(f, "\"null pointer dereference occurred\""),
288-
InvalidEnumConstruction(source) => {
289-
write!(f, "\"trying to construct an enum from an invalid value {{}}\", {source:?}")
288+
InvalidEnumConstruction(ty, source) => {
289+
write!(
290+
f,
291+
"\"trying to construct an enum from an invalid value {{}}; type {{}}\", {source:?}, {ty:?}"
292+
)
290293
}
291294
ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
292295
write!(f, "\"coroutine resumed after completion\"")
@@ -379,7 +382,7 @@ impl<O> AssertKind<O> {
379382
msg!("coroutine resumed after panicking")
380383
}
381384
NullPointerDereference => msg!("null pointer dereference occurred"),
382-
InvalidEnumConstruction(_) => {
385+
InvalidEnumConstruction(..) => {
383386
msg!("trying to construct an enum from an invalid value `{$source}`")
384387
}
385388
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
@@ -437,8 +440,9 @@ impl<O> AssertKind<O> {
437440
add!("required", format!("{required:#?}"));
438441
add!("found", format!("{found:#?}"));
439442
}
440-
InvalidEnumConstruction(source) => {
443+
InvalidEnumConstruction(ty, source) => {
441444
add!("source", format!("{source:#?}"));
445+
add!("ty", format!("{ty:#?}"));
442446
}
443447
}
444448
}

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,11 @@ macro_rules! make_mir_visitor {
685685
self.visit_operand(l, location);
686686
self.visit_operand(r, location);
687687
}
688-
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) | InvalidEnumConstruction(op) => {
688+
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
689+
self.visit_operand(op, location);
690+
}
691+
InvalidEnumConstruction(ty, op) => {
692+
self.visit_operand(ty, location);
689693
self.visit_operand(op, location);
690694
}
691695
ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference | ResumedAfterDrop(_) => {

compiler/rustc_mir_transform/src/check_enums.rs

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc_abi::{HasDataLayout, Scalar, Size, TagEncoding, Variants, WrappingRange};
2+
use rustc_const_eval::interpret::CTFE_ALLOC_SALT;
23
use rustc_hir::LangItem;
34
use rustc_index::IndexVec;
45
use rustc_middle::bug;
@@ -7,6 +8,7 @@ use rustc_middle::mir::*;
78
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt};
89
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypingEnv};
910
use rustc_session::Session;
11+
use rustc_span::DUMMY_SP;
1012
use tracing::debug;
1113

1214
/// This pass inserts checks for a valid enum discriminant where they are most
@@ -268,23 +270,24 @@ impl<'a, 'tcx> Visitor<'tcx> for EnumFinder<'a, 'tcx> {
268270

269271
let (enum_ty, enum_adt_def) = if enum_adt_def.is_enum() {
270272
(pointee_ty, enum_adt_def)
271-
} else if enum_adt_def.is_manually_drop() {
272-
// Find the type contained in the ManuallyDrop and check whether it is an enum.
273-
let Some((manual_drop_arg, adt_def)) =
274-
pointee_ty.walk().skip(1).next().map_or(None, |arg| {
275-
if let Some(ty) = arg.as_type()
276-
&& let ty::Adt(adt_def, _) = ty.kind()
277-
{
278-
Some((ty, adt_def))
279-
} else {
280-
None
281-
}
282-
})
283-
else {
284-
return;
285-
};
286273

287-
(manual_drop_arg, adt_def)
274+
// } else if enum_adt_def.is_manually_drop() {
275+
// // Find the type contained in the ManuallyDrop and check whether it is an enum.
276+
// let Some((manual_drop_arg, adt_def)) =
277+
// pointee_ty.walk().skip(1).next().map_or(None, |arg| {
278+
// if let Some(ty) = arg.as_type()
279+
// && let ty::Adt(adt_def, _) = ty.kind()
280+
// {
281+
// Some((ty, adt_def))
282+
// } else {
283+
// None
284+
// }
285+
// })
286+
// else {
287+
// return;
288+
// };
289+
290+
// (manual_drop_arg, adt_def)
288291
} else {
289292
return;
290293
};
@@ -504,7 +507,7 @@ fn insert_direct_enum_check<'tcx>(
504507
tcx,
505508
local_decls,
506509
block_data,
507-
source_op,
510+
source_op.clone(),
508511
discr,
509512
op_size,
510513
None,
@@ -544,6 +547,9 @@ fn insert_direct_enum_check<'tcx>(
544547
},
545548
});
546549

550+
let debug_str = format!("{:#?}", source_op.ty(local_decls, tcx));
551+
let allocation =
552+
tcx.allocate_bytes_dedup(std::borrow::Cow::Borrowed(debug_str.as_bytes()), CTFE_ALLOC_SALT);
547553
// Abort in case of an invalid enum discriminant.
548554
basic_blocks[invalid_discr_block].terminator = Some(Terminator {
549555
source_info,
@@ -555,7 +561,17 @@ fn insert_direct_enum_check<'tcx>(
555561
})),
556562
expected: true,
557563
target: new_block,
558-
msg: Box::new(AssertKind::InvalidEnumConstruction(Operand::Copy(discr_masked))),
564+
msg: Box::new(AssertKind::InvalidEnumConstruction(
565+
Operand::Constant(Box::new(ConstOperand {
566+
span: DUMMY_SP,
567+
user_ty: None,
568+
const_: Const::Val(
569+
ConstValue::Slice { alloc_id: allocation, meta: debug_str.len() as u64 },
570+
Ty::new_ref(tcx, tcx.lifetimes.re_erased, tcx.types.str_, Mutability::Not),
571+
),
572+
})),
573+
Operand::Copy(discr_masked),
574+
)),
559575
// This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
560576
// We never want to insert an unwind into unsafe code, because unwinding could
561577
// make a failing UB check turn into much worse UB when we start unwinding.
@@ -585,19 +601,30 @@ fn insert_uninhabited_enum_check<'tcx>(
585601
))),
586602
));
587603

604+
let debug_str = "None".to_owned();
605+
let allocation =
606+
tcx.allocate_bytes_dedup(std::borrow::Cow::Borrowed(debug_str.as_bytes()), CTFE_ALLOC_SALT);
588607
block_data.terminator = Some(Terminator {
589608
source_info,
590609
kind: TerminatorKind::Assert {
591610
cond: Operand::Copy(is_ok),
592611
expected: true,
593612
target: new_block,
594-
msg: Box::new(AssertKind::InvalidEnumConstruction(Operand::Constant(Box::new(
595-
ConstOperand {
613+
msg: Box::new(AssertKind::InvalidEnumConstruction(
614+
Operand::Constant(Box::new(ConstOperand {
615+
span: DUMMY_SP,
616+
user_ty: None,
617+
const_: Const::Val(
618+
ConstValue::Slice { alloc_id: allocation, meta: debug_str.len() as u64 },
619+
Ty::new_ref(tcx, tcx.lifetimes.re_erased, tcx.types.str_, Mutability::Not),
620+
),
621+
})),
622+
Operand::Constant(Box::new(ConstOperand {
596623
span: source_info.span,
597624
user_ty: None,
598625
const_: Const::Val(ConstValue::from_u128(0), tcx.types.u128),
599-
},
600-
)))),
626+
})),
627+
)),
601628
// This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
602629
// We never want to insert an unwind into unsafe code, because unwinding could
603630
// make a failing UB check turn into much worse UB when we start unwinding.
@@ -622,7 +649,7 @@ fn insert_niche_check<'tcx>(
622649
tcx,
623650
local_decls,
624651
block_data,
625-
source_op,
652+
source_op.clone(),
626653
discr,
627654
op_size,
628655
Some(offset),
@@ -668,13 +695,26 @@ fn insert_niche_check<'tcx>(
668695
))),
669696
));
670697

698+
let debug_str = format!("{:#?}", source_op.ty(local_decls, tcx));
699+
let allocation =
700+
tcx.allocate_bytes_dedup(std::borrow::Cow::Borrowed(debug_str.as_bytes()), CTFE_ALLOC_SALT);
671701
block_data.terminator = Some(Terminator {
672702
source_info,
673703
kind: TerminatorKind::Assert {
674704
cond: Operand::Copy(is_ok),
675705
expected: true,
676706
target: new_block,
677-
msg: Box::new(AssertKind::InvalidEnumConstruction(Operand::Copy(discr))),
707+
msg: Box::new(AssertKind::InvalidEnumConstruction(
708+
Operand::Constant(Box::new(ConstOperand {
709+
span: DUMMY_SP,
710+
user_ty: None,
711+
const_: Const::Val(
712+
ConstValue::Slice { alloc_id: allocation, meta: debug_str.len() as u64 },
713+
Ty::new_ref(tcx, tcx.lifetimes.re_erased, tcx.types.str_, Mutability::Not),
714+
),
715+
})),
716+
Operand::Copy(discr),
717+
)),
678718
// This calls panic_invalid_enum_construction, which is #[rustc_nounwind].
679719
// We never want to insert an unwind into unsafe code, because unwinding could
680720
// make a failing UB check turn into much worse UB when we start unwinding.

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
905905
mir::AssertKind::NullPointerDereference => {
906906
push_mono_lang_item(self, LangItem::PanicNullPointerDereference);
907907
}
908-
mir::AssertKind::InvalidEnumConstruction(_) => {
908+
mir::AssertKind::InvalidEnumConstruction(..) => {
909909
push_mono_lang_item(self, LangItem::PanicInvalidEnumConstruction);
910910
}
911911
_ => {

compiler/rustc_public/src/mir/body.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ pub enum AssertMessage {
269269
ResumedAfterDrop(CoroutineKind),
270270
MisalignedPointerDereference { required: Operand, found: Operand },
271271
NullPointerDereference,
272-
InvalidEnumConstruction(Operand),
272+
InvalidEnumConstruction(Operand, Operand),
273273
}
274274

275275
impl AssertMessage {
@@ -342,7 +342,7 @@ impl AssertMessage {
342342
Ok("misaligned pointer dereference")
343343
}
344344
AssertMessage::NullPointerDereference => Ok("null pointer dereference occurred"),
345-
AssertMessage::InvalidEnumConstruction(_) => {
345+
AssertMessage::InvalidEnumConstruction(..) => {
346346
Ok("trying to construct an enum from an invalid value")
347347
}
348348
}

compiler/rustc_public/src/mir/pretty.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,13 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R
311311
AssertMessage::NullPointerDereference => {
312312
write!(writer, "\"null pointer dereference occurred\"")
313313
}
314-
AssertMessage::InvalidEnumConstruction(op) => {
314+
AssertMessage::InvalidEnumConstruction(ty, op) => {
315+
let pretty_ty = pretty_operand(ty);
315316
let pretty_op = pretty_operand(op);
316-
write!(writer, "\"trying to construct an enum from an invalid value {{}}\",{pretty_op}")
317+
write!(
318+
writer,
319+
"\"trying to construct an enum from an invalid value {{}}, ty {{}}\",{pretty_op},{pretty_ty}"
320+
)
317321
}
318322
AssertMessage::ResumedAfterReturn(_)
319323
| AssertMessage::ResumedAfterPanic(_)

0 commit comments

Comments
 (0)