Skip to content

Commit 2ef2ac0

Browse files
committed
Make type validation buffer errors.
1 parent 030589d commit 2ef2ac0

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ impl<'tcx> MirPass<'tcx> for Validator {
7272
cfg_checker.visit_body(body);
7373
cfg_checker.check_cleanup_control_flow();
7474

75-
let mut type_checker = TypeChecker { when: &self.when, body, tcx, param_env, mir_phase };
76-
type_checker.visit_body(body);
75+
for (location, msg) in validate_types(tcx, self.mir_phase, param_env, body) {
76+
cfg_checker.fail(location, msg);
77+
}
7778

7879
if let MirPhase::Runtime(_) = body.phase {
7980
if let ty::InstanceDef::Item(_) = body.source.instance {
@@ -498,30 +499,28 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
498499
}
499500
}
500501

502+
fn validate_types<'tcx>(
503+
tcx: TyCtxt<'tcx>,
504+
mir_phase: MirPhase,
505+
param_env: ty::ParamEnv<'tcx>,
506+
body: &Body<'tcx>,
507+
) -> Vec<(Location, String)> {
508+
let mut type_checker = TypeChecker { body, tcx, param_env, mir_phase, failures: Vec::new() };
509+
type_checker.visit_body(body);
510+
type_checker.failures
511+
}
512+
501513
struct TypeChecker<'a, 'tcx> {
502-
when: &'a str,
503514
body: &'a Body<'tcx>,
504515
tcx: TyCtxt<'tcx>,
505516
param_env: ParamEnv<'tcx>,
506517
mir_phase: MirPhase,
518+
failures: Vec<(Location, String)>,
507519
}
508520

509521
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
510-
#[track_caller]
511-
fn fail(&self, location: Location, msg: impl AsRef<str>) {
512-
let span = self.body.source_info(location).span;
513-
// We use `delay_span_bug` as we might see broken MIR when other errors have already
514-
// occurred.
515-
self.tcx.sess.diagnostic().delay_span_bug(
516-
span,
517-
format!(
518-
"broken MIR in {:?} ({}) at {:?}:\n{}",
519-
self.body.source.instance,
520-
self.when,
521-
location,
522-
msg.as_ref()
523-
),
524-
);
522+
fn fail(&mut self, location: Location, msg: impl Into<String>) {
523+
self.failures.push((location, msg.into()));
525524
}
526525

527526
/// Check if src can be assigned into dest.
@@ -593,10 +592,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
593592
}
594593
ProjectionElem::Field(f, ty) => {
595594
let parent_ty = place_ref.ty(&self.body.local_decls, self.tcx);
596-
let fail_out_of_bounds = |this: &Self, location| {
595+
let fail_out_of_bounds = |this: &mut Self, location| {
597596
this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
598597
};
599-
let check_equal = |this: &Self, location, f_ty| {
598+
let check_equal = |this: &mut Self, location, f_ty| {
600599
if !this.mir_assign_valid_types(ty, f_ty) {
601600
this.fail(
602601
location,
@@ -691,9 +690,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
691690
}
692691

693692
fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) {
694-
let check_place = |place: Place<'_>| {
693+
let check_place = |this: &mut Self, place: Place<'_>| {
695694
if place.projection.iter().any(|p| !p.can_use_in_debuginfo()) {
696-
self.fail(
695+
this.fail(
697696
START_BLOCK.start_location(),
698697
format!("illegal place {:?} in debuginfo for {:?}", place, debuginfo.name),
699698
);
@@ -702,7 +701,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
702701
match debuginfo.value {
703702
VarDebugInfoContents::Const(_) => {}
704703
VarDebugInfoContents::Place(place) => {
705-
check_place(place);
704+
check_place(self, place);
706705
if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) {
707706
self.fail(
708707
START_BLOCK.start_location(),
@@ -712,7 +711,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
712711
}
713712
VarDebugInfoContents::Composite { ty, ref fragments } => {
714713
for f in fragments {
715-
check_place(f.contents);
714+
check_place(self, f.contents);
716715
if ty.is_union() || ty.is_enum() {
717716
self.fail(
718717
START_BLOCK.start_location(),
@@ -969,7 +968,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
969968
}
970969
}
971970
Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => {
972-
let fail_out_of_bounds = |this: &Self, location, field, ty| {
971+
let fail_out_of_bounds = |this: &mut Self, location, field, ty| {
973972
this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
974973
};
975974

0 commit comments

Comments
 (0)