1- //! Propagates constants for early reporting of statically known
2- //! assertion failures
1+ //! A lint that checks constant operations for
2+ //! errors like overflows, division by zero,
3+ //! out-of-bound access etc.
4+ //! Uses const propagation to determine the
5+ //! values of operands during checks.
36
47use std:: fmt:: Debug ;
58
@@ -21,9 +24,9 @@ use crate::dataflow_const_prop::DummyMachine;
2124use crate :: errors:: { AssertLint , AssertLintKind } ;
2225use crate :: MirLint ;
2326
24- pub struct ConstPropLint ;
27+ pub struct OverflowLint ;
2528
26- impl < ' tcx > MirLint < ' tcx > for ConstPropLint {
29+ impl < ' tcx > MirLint < ' tcx > for OverflowLint {
2730 fn run_lint ( & self , tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > ) {
2831 if body. tainted_by_errors . is_some ( ) {
2932 return ;
@@ -37,31 +40,28 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
3740 // Only run const prop on functions, methods, closures and associated constants
3841 if !is_fn_like && !is_assoc_const {
3942 // skip anon_const/statics/consts because they'll be evaluated by miri anyway
40- trace ! ( "ConstPropLint skipped for {:?}" , def_id) ;
43+ trace ! ( "OverflowLint skipped for {:?}" , def_id) ;
4144 return ;
4245 }
4346
4447 // FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles
4548 // computing their layout.
4649 if tcx. is_coroutine ( def_id. to_def_id ( ) ) {
47- trace ! ( "ConstPropLint skipped for coroutine {:?}" , def_id) ;
50+ trace ! ( "OverflowLint skipped for coroutine {:?}" , def_id) ;
4851 return ;
4952 }
5053
51- trace ! ( "ConstPropLint starting for {:?}" , def_id) ;
54+ trace ! ( "OverflowLint starting for {:?}" , def_id) ;
5255
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).
5756 let mut linter = ConstPropagator :: new ( body, tcx) ;
5857 linter. visit_body ( body) ;
5958
60- trace ! ( "ConstPropLint done for {:?}" , def_id) ;
59+ trace ! ( "OverflowLint done for {:?}" , def_id) ;
6160 }
6261}
6362
64- /// Finds optimization opportunities on the MIR.
63+ /// Visits MIR nodes, performs const propagation
64+ /// and runs lint checks as it goes
6565struct ConstPropagator < ' mir , ' tcx > {
6666 ecx : InterpCx < ' mir , ' tcx , DummyMachine > ,
6767 tcx : TyCtxt < ' tcx > ,
@@ -238,7 +238,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
238238 // dedicated error variants should be introduced instead.
239239 assert ! (
240240 !error. kind( ) . formatted_string( ) ,
241- "const-prop encountered formatting error: {}" ,
241+ "overflow lint encountered formatting error: {}" ,
242242 format_interp_error( self . ecx. tcx. dcx( ) , error) ,
243243 ) ;
244244 None
@@ -253,7 +253,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
253253 return None ;
254254 }
255255
256- // Normalization needed b/c const prop lint runs in
256+ // Normalization needed b/c overflow lint runs in
257257 // `mir_drops_elaborated_and_const_checked`, which happens before
258258 // optimized MIR. Only after optimizing the MIR can we guarantee
259259 // that the `RevealAll` pass has happened and that the body's consts
@@ -864,6 +864,8 @@ pub enum ConstPropMode {
864864 NoPropagation ,
865865}
866866
867+ /// A visitor that determines locals in a MIR body
868+ /// that can be const propagated
867869pub struct CanConstProp {
868870 can_const_prop : IndexVec < Local , ConstPropMode > ,
869871 // False at the beginning. Once set, no more assignments are allowed to that local.
0 commit comments