Rename ConstPropLint to KnownPanicsLint

It is a clearer name because it communicates what the lint does
instead of the underlying mechanism it uses (const propagation).
This commit is contained in:
Gurinder Singh 2024-02-20 07:41:48 +05:30
parent 61223975d4
commit 42c4df01a8
2 changed files with 19 additions and 17 deletions

View File

@ -1,5 +1,8 @@
//! Propagates constants for early reporting of statically known //! A lint that checks for known panics like
//! assertion failures //! overflows, division by zero,
//! out-of-bound access etc.
//! Uses const propagation to determine the
//! values of operands during checks.
use std::fmt::Debug; use std::fmt::Debug;
@ -21,9 +24,9 @@ use crate::dataflow_const_prop::DummyMachine;
use crate::errors::{AssertLint, AssertLintKind}; use crate::errors::{AssertLint, AssertLintKind};
use crate::MirLint; use crate::MirLint;
pub struct ConstPropLint; pub struct KnownPanicsLint;
impl<'tcx> MirLint<'tcx> for ConstPropLint { impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
if body.tainted_by_errors.is_some() { if body.tainted_by_errors.is_some() {
return; return;
@ -37,31 +40,28 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
// Only run const prop on functions, methods, closures and associated constants // Only run const prop on functions, methods, closures and associated constants
if !is_fn_like && !is_assoc_const { if !is_fn_like && !is_assoc_const {
// skip anon_const/statics/consts because they'll be evaluated by miri anyway // skip anon_const/statics/consts because they'll be evaluated by miri anyway
trace!("ConstPropLint skipped for {:?}", def_id); trace!("KnownPanicsLint skipped for {:?}", def_id);
return; return;
} }
// FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles // FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles
// computing their layout. // computing their layout.
if tcx.is_coroutine(def_id.to_def_id()) { if tcx.is_coroutine(def_id.to_def_id()) {
trace!("ConstPropLint skipped for coroutine {:?}", def_id); trace!("KnownPanicsLint skipped for coroutine {:?}", def_id);
return; return;
} }
trace!("ConstPropLint starting for {:?}", def_id); trace!("KnownPanicsLint starting for {:?}", def_id);
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
// constants, instead of just checking for const-folding succeeding.
// That would require a uniform one-def no-mutation analysis
// and RPO (or recursing when needing the value of a local).
let mut linter = ConstPropagator::new(body, tcx); let mut linter = ConstPropagator::new(body, tcx);
linter.visit_body(body); linter.visit_body(body);
trace!("ConstPropLint done for {:?}", def_id); trace!("KnownPanicsLint done for {:?}", def_id);
} }
} }
/// Finds optimization opportunities on the MIR. /// Visits MIR nodes, performs const propagation
/// and runs lint checks as it goes
struct ConstPropagator<'mir, 'tcx> { struct ConstPropagator<'mir, 'tcx> {
ecx: InterpCx<'mir, 'tcx, DummyMachine>, ecx: InterpCx<'mir, 'tcx, DummyMachine>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
@ -238,7 +238,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// dedicated error variants should be introduced instead. // dedicated error variants should be introduced instead.
assert!( assert!(
!error.kind().formatted_string(), !error.kind().formatted_string(),
"const-prop encountered formatting error: {}", "known panics lint encountered formatting error: {}",
format_interp_error(self.ecx.tcx.dcx(), error), format_interp_error(self.ecx.tcx.dcx(), error),
); );
None None
@ -253,7 +253,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None; return None;
} }
// Normalization needed b/c const prop lint runs in // Normalization needed b/c known panics lint runs in
// `mir_drops_elaborated_and_const_checked`, which happens before // `mir_drops_elaborated_and_const_checked`, which happens before
// optimized MIR. Only after optimizing the MIR can we guarantee // optimized MIR. Only after optimizing the MIR can we guarantee
// that the `RevealAll` pass has happened and that the body's consts // that the `RevealAll` pass has happened and that the body's consts
@ -864,6 +864,8 @@ pub enum ConstPropMode {
NoPropagation, NoPropagation,
} }
/// A visitor that determines locals in a MIR body
/// that can be const propagated
pub struct CanConstProp { pub struct CanConstProp {
can_const_prop: IndexVec<Local, ConstPropMode>, can_const_prop: IndexVec<Local, ConstPropMode>,
// False at the beginning. Once set, no more assignments are allowed to that local. // False at the beginning. Once set, no more assignments are allowed to that local.

View File

@ -59,7 +59,6 @@ mod remove_place_mention;
mod add_subtyping_projections; mod add_subtyping_projections;
pub mod cleanup_post_borrowck; pub mod cleanup_post_borrowck;
mod const_debuginfo; mod const_debuginfo;
mod const_prop_lint;
mod copy_prop; mod copy_prop;
mod coroutine; mod coroutine;
mod cost_checker; mod cost_checker;
@ -83,6 +82,7 @@ mod gvn;
pub mod inline; pub mod inline;
mod instsimplify; mod instsimplify;
mod jump_threading; mod jump_threading;
mod known_panics_lint;
mod large_enums; mod large_enums;
mod lint; mod lint;
mod lower_intrinsics; mod lower_intrinsics;
@ -533,7 +533,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&elaborate_box_derefs::ElaborateBoxDerefs, &elaborate_box_derefs::ElaborateBoxDerefs,
&coroutine::StateTransform, &coroutine::StateTransform,
&add_retag::AddRetag, &add_retag::AddRetag,
&Lint(const_prop_lint::ConstPropLint), &Lint(known_panics_lint::KnownPanicsLint),
]; ];
pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial))); pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
} }