Skip to content

Commit 9462e73

Browse files
committed
MIR validation: ensure that debuginfo records are not emitted for locals that are not in debuginfo
1 parent 690071c commit 9462e73

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_middle::ty::{
1717
self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance,
1818
};
1919
use rustc_middle::{bug, span_bug};
20+
use rustc_mir_dataflow::debuginfo::debuginfo_locals;
2021
use rustc_trait_selection::traits::ObligationCtxt;
2122

2223
use crate::util::{self, is_within_packed};
@@ -80,6 +81,11 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
8081
cfg_checker.fail(location, msg);
8182
}
8283

84+
// Ensure that debuginfo records are not emitted for locals that are not in debuginfo.
85+
for (location, msg) in validate_debuginfos(body) {
86+
cfg_checker.fail(location, msg);
87+
}
88+
8389
if let MirPhase::Runtime(_) = body.phase
8490
&& let ty::InstanceKind::Item(_) = body.source.instance
8591
&& body.has_free_regions()
@@ -1595,3 +1601,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
15951601
self.super_terminator(terminator, location);
15961602
}
15971603
}
1604+
1605+
pub(super) fn validate_debuginfos<'tcx>(body: &Body<'tcx>) -> Vec<(Location, String)> {
1606+
let mut debuginfo_checker =
1607+
DebuginfoChecker { debuginfo_locals: debuginfo_locals(body), failures: Vec::new() };
1608+
debuginfo_checker.visit_body(body);
1609+
debuginfo_checker.failures
1610+
}
1611+
1612+
struct DebuginfoChecker {
1613+
debuginfo_locals: DenseBitSet<Local>,
1614+
failures: Vec<(Location, String)>,
1615+
}
1616+
1617+
impl<'tcx> Visitor<'tcx> for DebuginfoChecker {
1618+
fn visit_statement_debuginfo(
1619+
&mut self,
1620+
stmt_debuginfo: &StmtDebugInfo<'tcx>,
1621+
location: Location,
1622+
) {
1623+
let local = match stmt_debuginfo {
1624+
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => *local,
1625+
};
1626+
if !self.debuginfo_locals.contains(local) {
1627+
self.failures.push((location, format!("{local:?} is not in debuginfo")));
1628+
}
1629+
}
1630+
}

0 commit comments

Comments
 (0)