1
- //! Propagates constants for early reporting of statically known
2
- //! assertion failures
1
+ //! A lint that checks for known panics like
2
+ //! overflows, division by zero,
3
+ //! out-of-bound access etc.
4
+ //! Uses const propagation to determine the
5
+ //! values of operands during checks.
3
6
4
7
use std::fmt::Debug;
5
8
@@ -21,9 +24,9 @@ use crate::dataflow_const_prop::DummyMachine;
21
24
use crate::errors::{AssertLint, AssertLintKind};
22
25
use crate::MirLint;
23
26
24
- pub struct ConstPropLint ;
27
+ pub struct KnownPanicsLint ;
25
28
26
- impl<'tcx> MirLint<'tcx> for ConstPropLint {
29
+ impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
27
30
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
28
31
if body.tainted_by_errors.is_some() {
29
32
return;
@@ -37,31 +40,28 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
37
40
// Only run const prop on functions, methods, closures and associated constants
38
41
if !is_fn_like && !is_assoc_const {
39
42
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
40
- trace!("ConstPropLint skipped for {:?}", def_id);
43
+ trace!("KnownPanicsLint skipped for {:?}", def_id);
41
44
return;
42
45
}
43
46
44
47
// FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles
45
48
// computing their layout.
46
49
if tcx.is_coroutine(def_id.to_def_id()) {
47
- trace!("ConstPropLint skipped for coroutine {:?}", def_id);
50
+ trace!("KnownPanicsLint skipped for coroutine {:?}", def_id);
48
51
return;
49
52
}
50
53
51
- trace!("ConstPropLint starting for {:?}", def_id);
54
+ trace!("KnownPanicsLint starting for {:?}", def_id);
52
55
53
- // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
54
- // constants, instead of just checking for const-folding succeeding.
55
- // That would require a uniform one-def no-mutation analysis
56
- // and RPO (or recursing when needing the value of a local).
57
56
let mut linter = ConstPropagator::new(body, tcx);
58
57
linter.visit_body(body);
59
58
60
- trace!("ConstPropLint done for {:?}", def_id);
59
+ trace!("KnownPanicsLint done for {:?}", def_id);
61
60
}
62
61
}
63
62
64
- /// Finds optimization opportunities on the MIR.
63
+ /// Visits MIR nodes, performs const propagation
64
+ /// and runs lint checks as it goes
65
65
struct ConstPropagator<'mir, 'tcx> {
66
66
ecx: InterpCx<'mir, 'tcx, DummyMachine>,
67
67
tcx: TyCtxt<'tcx>,
@@ -238,7 +238,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
238
238
// dedicated error variants should be introduced instead.
239
239
assert!(
240
240
!error.kind().formatted_string(),
241
- "const-prop encountered formatting error: {}",
241
+ "known panics lint encountered formatting error: {}",
242
242
format_interp_error(self.ecx.tcx.dcx(), error),
243
243
);
244
244
None
@@ -253,7 +253,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
253
253
return None;
254
254
}
255
255
256
- // Normalization needed b/c const prop lint runs in
256
+ // Normalization needed b/c known panics lint runs in
257
257
// `mir_drops_elaborated_and_const_checked`, which happens before
258
258
// optimized MIR. Only after optimizing the MIR can we guarantee
259
259
// that the `RevealAll` pass has happened and that the body's consts
@@ -864,6 +864,8 @@ pub enum ConstPropMode {
864
864
NoPropagation,
865
865
}
866
866
867
+ /// A visitor that determines locals in a MIR body
868
+ /// that can be const propagated
867
869
pub struct CanConstProp {
868
870
can_const_prop: IndexVec<Local, ConstPropMode>,
869
871
// False at the beginning. Once set, no more assignments are allowed to that local.
0 commit comments