Rollup merge of #115972 - RalfJung:const-consistency, r=oli-obk
rename mir::Constant -> mir::ConstOperand, mir::ConstKind -> mir::Const Also, be more consistent with the `to/eval_bits` methods... we had some that take a type and some that take a size, and then sometimes the one that takes a type is called `bits_for_ty`. Turns out that `ty::Const`/`mir::ConstKind` carry their type with them, so we don't need to even pass the type to those `eval_bits` functions at all. However this is not properly consistent yet: in `ty` we have most of the methods on `ty::Const`, but in `mir` we have them on `mir::ConstKind`. And indeed those two types are the ones that correspond to each other. So `mir::ConstantKind` should actually be renamed to `mir::Const`. But what to do with `mir::Constant`? It carries around a span, that's really more like a constant operand that appears as a MIR operand... it's more suited for `syntax.rs` than `consts.rs`, but the bigger question is, which name should it get if we want to align the `mir` and `ty` types? `ConstOperand`? `ConstOp`? `Literal`? It's not a literal but it has a field called `literal` so it would at least be consistently wrong-ish... ``@oli-obk`` any ideas?
This commit is contained in:
commit
208f6ed95c
76 changed files with 461 additions and 493 deletions
|
@ -181,13 +181,10 @@ fn insert_alignment_check<'tcx>(
|
|||
// Subtract 1 from the alignment to get the alignment mask
|
||||
let alignment_mask =
|
||||
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
|
||||
let one = Operand::Constant(Box::new(Constant {
|
||||
let one = Operand::Constant(Box::new(ConstOperand {
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(
|
||||
ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)),
|
||||
tcx.types.usize,
|
||||
),
|
||||
const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)), tcx.types.usize),
|
||||
}));
|
||||
block_data.statements.push(Statement {
|
||||
source_info,
|
||||
|
@ -213,13 +210,10 @@ fn insert_alignment_check<'tcx>(
|
|||
|
||||
// Check if the alignment bits are all zero
|
||||
let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into();
|
||||
let zero = Operand::Constant(Box::new(Constant {
|
||||
let zero = Operand::Constant(Box::new(ConstOperand {
|
||||
span: source_info.span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(
|
||||
ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)),
|
||||
tcx.types.usize,
|
||||
),
|
||||
const_: Const::Val(ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), tcx.types.usize),
|
||||
}));
|
||||
block_data.statements.push(Statement {
|
||||
source_info,
|
||||
|
|
|
@ -142,9 +142,9 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
|||
|
||||
fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
|
||||
if let Operand::Constant(constant) = op {
|
||||
let maybe_uneval = match constant.literal {
|
||||
ConstantKind::Val(..) | ConstantKind::Ty(_) => None,
|
||||
ConstantKind::Unevaluated(uv, _) => Some(uv),
|
||||
let maybe_uneval = match constant.const_ {
|
||||
Const::Val(..) | Const::Ty(_) => None,
|
||||
Const::Unevaluated(uv, _) => Some(uv),
|
||||
};
|
||||
|
||||
if let Some(uv) = maybe_uneval {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use rustc_middle::{
|
||||
mir::{
|
||||
visit::{PlaceContext, Visitor},
|
||||
Body, Constant, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents,
|
||||
Body, ConstOperand, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents,
|
||||
},
|
||||
ty::TyCtxt,
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ struct LocalUseVisitor {
|
|||
local_assignment_locations: IndexVec<Local, Option<Location>>,
|
||||
}
|
||||
|
||||
fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Constant<'tcx>)> {
|
||||
fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, ConstOperand<'tcx>)> {
|
||||
let mut visitor = LocalUseVisitor {
|
||||
local_mutating_uses: IndexVec::from_elem(0, &body.local_decls),
|
||||
local_assignment_locations: IndexVec::from_elem(None, &body.local_decls),
|
||||
|
|
|
@ -96,10 +96,10 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
|
|||
let (discr, targets) = target_bb_terminator.kind.as_switch()?;
|
||||
if discr.place() == Some(*place) {
|
||||
let switch_ty = place.ty(self.body.local_decls(), self.tcx).ty;
|
||||
debug_assert_eq!(switch_ty, _const.ty());
|
||||
// We now know that the Switch matches on the const place, and it is statementless
|
||||
// Now find which value in the Switch matches the const value.
|
||||
let const_value =
|
||||
_const.literal.try_eval_bits(self.tcx, self.param_env, switch_ty)?;
|
||||
let const_value = _const.const_.try_eval_bits(self.tcx, self.param_env)?;
|
||||
let target_to_use_in_goto = targets.target_for_value(const_value);
|
||||
self.optimizations.push(OptimizationToApply {
|
||||
bb_with_goto: location.block,
|
||||
|
|
|
@ -525,7 +525,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn replace_with_const(&mut self, place: Place<'tcx>) -> Option<ConstantKind<'tcx>> {
|
||||
fn replace_with_const(&mut self, place: Place<'tcx>) -> Option<Const<'tcx>> {
|
||||
// This will return None if the above `const_prop` invocation only "wrote" a
|
||||
// type whose creation requires no write. E.g. a generator whose initial state
|
||||
// consists solely of uninitialized memory (so it doesn't capture any locals).
|
||||
|
@ -541,7 +541,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
let Right(imm) = imm else { return None };
|
||||
match *imm {
|
||||
Immediate::Scalar(scalar) if scalar.try_to_int().is_ok() => {
|
||||
Some(ConstantKind::from_scalar(self.tcx, scalar, value.layout.ty))
|
||||
Some(Const::from_scalar(self.tcx, scalar, value.layout.ty))
|
||||
}
|
||||
Immediate::ScalarPair(l, r) if l.try_to_int().is_ok() && r.try_to_int().is_ok() => {
|
||||
let alloc_id = self
|
||||
|
@ -551,7 +551,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
})
|
||||
.ok()?;
|
||||
|
||||
Some(ConstantKind::Val(
|
||||
Some(Const::Val(
|
||||
ConstValue::Indirect { alloc_id, offset: Size::ZERO },
|
||||
value.layout.ty,
|
||||
))
|
||||
|
@ -731,7 +731,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
|||
if let Some(()) = self.eval_rvalue_with_identities(rvalue, *place) {
|
||||
// If this was already an evaluated constant, keep it.
|
||||
if let Rvalue::Use(Operand::Constant(c)) = rvalue
|
||||
&& let ConstantKind::Val(..) = c.literal
|
||||
&& let Const::Val(..) = c.const_
|
||||
{
|
||||
trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c);
|
||||
} else if let Some(operand) = self.replace_with_const(*place) {
|
||||
|
|
|
@ -281,7 +281,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `c`.
|
||||
fn eval_constant(&mut self, c: &Constant<'tcx>, location: Location) -> Option<OpTy<'tcx>> {
|
||||
fn eval_constant(&mut self, c: &ConstOperand<'tcx>, location: Location) -> Option<OpTy<'tcx>> {
|
||||
// FIXME we need to revisit this for #67176
|
||||
if c.has_param() {
|
||||
return None;
|
||||
|
@ -293,7 +293,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
// that the `RevealAll` pass has happened and that the body's consts
|
||||
// are normalized, so any call to resolve before that needs to be
|
||||
// manually normalized.
|
||||
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?;
|
||||
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.const_).ok()?;
|
||||
|
||||
self.use_ecx(location, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None))
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
|
|||
self.super_operand(operand, location);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
|
||||
trace!("visit_constant: {:?}", constant);
|
||||
self.super_constant(constant, location);
|
||||
self.eval_constant(constant, location);
|
||||
|
|
|
@ -206,7 +206,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
&& let operand_ty = operand.ty(self.local_decls, self.tcx)
|
||||
&& let Some(operand_ty) = operand_ty.builtin_deref(true)
|
||||
&& let ty::Array(_, len) = operand_ty.ty.kind()
|
||||
&& let Some(len) = ConstantKind::Ty(*len).try_eval_scalar_int(self.tcx, self.param_env)
|
||||
&& let Some(len) = Const::Ty(*len).try_eval_scalar_int(self.tcx, self.param_env)
|
||||
{
|
||||
state.insert_value_idx(target_len, FlatSet::Elem(len.into()), self.map());
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
Rvalue::Len(place) => {
|
||||
let place_ty = place.ty(self.local_decls, self.tcx);
|
||||
if let ty::Array(_, len) = place_ty.ty.kind() {
|
||||
ConstantKind::Ty(*len)
|
||||
Const::Ty(*len)
|
||||
.try_eval_scalar(self.tcx, self.param_env)
|
||||
.map_or(FlatSet::Top, FlatSet::Elem)
|
||||
} else if let [ProjectionElem::Deref] = place.projection[..] {
|
||||
|
@ -295,11 +295,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
|
||||
fn handle_constant(
|
||||
&self,
|
||||
constant: &Constant<'tcx>,
|
||||
constant: &ConstOperand<'tcx>,
|
||||
_state: &mut State<Self::Value>,
|
||||
) -> Self::Value {
|
||||
constant
|
||||
.literal
|
||||
.const_
|
||||
.try_eval_scalar(self.tcx, self.param_env)
|
||||
.map_or(FlatSet::Top, FlatSet::Elem)
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
Operand::Constant(box constant) => {
|
||||
if let Ok(constant) = self.ecx.eval_mir_constant(&constant.literal, None, None) {
|
||||
if let Ok(constant) = self.ecx.eval_mir_constant(&constant.const_, None, None) {
|
||||
self.assign_constant(state, place, constant, &[]);
|
||||
}
|
||||
}
|
||||
|
@ -518,10 +518,10 @@ pub(crate) struct Patch<'tcx> {
|
|||
/// For a given MIR location, this stores the values of the operands used by that location. In
|
||||
/// particular, this is before the effect, such that the operands of `_1 = _1 + _2` are
|
||||
/// properly captured. (This may become UB soon, but it is currently emitted even by safe code.)
|
||||
pub(crate) before_effect: FxHashMap<(Location, Place<'tcx>), ConstantKind<'tcx>>,
|
||||
pub(crate) before_effect: FxHashMap<(Location, Place<'tcx>), Const<'tcx>>,
|
||||
|
||||
/// Stores the assigned values for assignments where the Rvalue is constant.
|
||||
pub(crate) assignments: FxHashMap<Location, ConstantKind<'tcx>>,
|
||||
pub(crate) assignments: FxHashMap<Location, Const<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Patch<'tcx> {
|
||||
|
@ -529,8 +529,8 @@ impl<'tcx> Patch<'tcx> {
|
|||
Self { tcx, before_effect: FxHashMap::default(), assignments: FxHashMap::default() }
|
||||
}
|
||||
|
||||
fn make_operand(&self, literal: ConstantKind<'tcx>) -> Operand<'tcx> {
|
||||
Operand::Constant(Box::new(Constant { span: DUMMY_SP, user_ty: None, literal }))
|
||||
fn make_operand(&self, const_: Const<'tcx>) -> Operand<'tcx> {
|
||||
Operand::Constant(Box::new(ConstOperand { span: DUMMY_SP, user_ty: None, const_ }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,12 +549,12 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> {
|
|||
place: Place<'tcx>,
|
||||
state: &State<FlatSet<Scalar>>,
|
||||
map: &Map,
|
||||
) -> Option<ConstantKind<'tcx>> {
|
||||
) -> Option<Const<'tcx>> {
|
||||
let FlatSet::Elem(Scalar::Int(value)) = state.get(place.as_ref(), &map) else {
|
||||
return None;
|
||||
};
|
||||
let ty = place.ty(self.local_decls, self.patch.tcx).ty;
|
||||
Some(ConstantKind::Val(ConstValue::Scalar(value.into()), ty))
|
||||
Some(Const::Val(ConstValue::Scalar(value.into()), ty))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ fn rvalue_hash<H: Hasher>(hasher: &mut H, rvalue: &Rvalue<'_>) {
|
|||
|
||||
fn operand_hash<H: Hasher>(hasher: &mut H, operand: &Operand<'_>) {
|
||||
match operand {
|
||||
Operand::Constant(box Constant { user_ty: _, literal, span: _ }) => literal.hash(hasher),
|
||||
Operand::Constant(box ConstOperand { user_ty: _, const_, span: _ }) => const_.hash(hasher),
|
||||
x => x.hash(hasher),
|
||||
};
|
||||
}
|
||||
|
@ -179,9 +179,9 @@ fn rvalue_eq<'tcx>(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool {
|
|||
fn operand_eq<'tcx>(lhs: &Operand<'tcx>, rhs: &Operand<'tcx>) -> bool {
|
||||
let res = match (lhs, rhs) {
|
||||
(
|
||||
Operand::Constant(box Constant { user_ty: _, literal, span: _ }),
|
||||
Operand::Constant(box Constant { user_ty: _, literal: literal2, span: _ }),
|
||||
) => literal == literal2,
|
||||
Operand::Constant(box ConstOperand { user_ty: _, const_, span: _ }),
|
||||
Operand::Constant(box ConstOperand { user_ty: _, const_: const2, span: _ }),
|
||||
) => const_ == const2,
|
||||
(x, y) => x == y,
|
||||
};
|
||||
debug!("operand_eq lhs: `{:?}` rhs: `{:?}` result: {:?}", lhs, rhs, res);
|
||||
|
|
|
@ -402,10 +402,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
|
||||
Rvalue::Use(Operand::Constant(Box::new(Constant {
|
||||
Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::from_bool(self.tcx, val),
|
||||
const_: Const::from_bool(self.tcx, val),
|
||||
})))
|
||||
}
|
||||
|
||||
|
|
|
@ -1189,10 +1189,10 @@ fn insert_panic_block<'tcx>(
|
|||
) -> BasicBlock {
|
||||
let assert_block = BasicBlock::new(body.basic_blocks.len());
|
||||
let term = TerminatorKind::Assert {
|
||||
cond: Operand::Constant(Box::new(Constant {
|
||||
cond: Operand::Constant(Box::new(ConstOperand {
|
||||
span: body.span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::from_bool(tcx, false),
|
||||
const_: Const::from_bool(tcx, false),
|
||||
})),
|
||||
expected: true,
|
||||
msg: Box::new(message),
|
||||
|
|
|
@ -652,11 +652,11 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
|
||||
// because we are calling `subst_and_normalize_erasing_regions`.
|
||||
caller_body.required_consts.extend(
|
||||
callee_body.required_consts.iter().copied().filter(|&ct| match ct.literal {
|
||||
ConstantKind::Ty(_) => {
|
||||
callee_body.required_consts.iter().copied().filter(|&ct| match ct.const_ {
|
||||
Const::Ty(_) => {
|
||||
bug!("should never encounter ty::UnevaluatedConst in `required_consts`")
|
||||
}
|
||||
ConstantKind::Val(..) | ConstantKind::Unevaluated(..) => true,
|
||||
Const::Val(..) | Const::Unevaluated(..) => true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -824,7 +824,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
||||
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.literal.ty()));
|
||||
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
|
||||
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
|
||||
// Don't give intrinsics the extra penalty for calls
|
||||
INSTR_COST
|
||||
|
|
|
@ -104,7 +104,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
|
||||
fn try_eval_bool(&self, a: &Operand<'_>) -> Option<bool> {
|
||||
let a = a.constant()?;
|
||||
if a.literal.ty().is_bool() { a.literal.try_to_bool() } else { None }
|
||||
if a.const_.ty().is_bool() { a.const_.try_to_bool() } else { None }
|
||||
}
|
||||
|
||||
/// Transform "&(*a)" ==> "a".
|
||||
|
@ -136,8 +136,8 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
return;
|
||||
}
|
||||
|
||||
let literal = ConstantKind::from_ty_const(len, self.tcx);
|
||||
let constant = Constant { span: source_info.span, literal, user_ty: None };
|
||||
let const_ = Const::from_ty_const(len, self.tcx);
|
||||
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
|
||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,10 +149,10 @@ impl EnumSizeOpt {
|
|||
};
|
||||
|
||||
let place = Place::from(size_array_local);
|
||||
let constant_vals = Constant {
|
||||
let constant_vals = ConstOperand {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(
|
||||
const_: Const::Val(
|
||||
ConstValue::Indirect { alloc_id, offset: Size::ZERO },
|
||||
tmp_ty,
|
||||
),
|
||||
|
|
|
@ -31,9 +31,9 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{
|
||||
traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstQualifs, Constant, LocalDecl,
|
||||
MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs,
|
||||
LocalDecl, MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue,
|
||||
SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
|
@ -149,14 +149,14 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
|||
let terminator = bb.terminator.as_mut().expect("invalid terminator");
|
||||
match terminator.kind {
|
||||
TerminatorKind::Call {
|
||||
func: Operand::Constant(box Constant { ref literal, .. }),
|
||||
func: Operand::Constant(box ConstOperand { ref const_, .. }),
|
||||
ref mut args,
|
||||
destination,
|
||||
target,
|
||||
unwind,
|
||||
fn_span,
|
||||
..
|
||||
} if let ty::FnDef(def_id, _) = *literal.ty().kind()
|
||||
} if let ty::FnDef(def_id, _) = *const_.ty().kind()
|
||||
&& tcx.item_name(def_id) == sym::const_eval_select
|
||||
&& tcx.is_intrinsic(def_id) =>
|
||||
{
|
||||
|
|
|
@ -32,10 +32,10 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Use(Operand::Constant(Box::new(Constant {
|
||||
Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
|
||||
span: terminator.source_info.span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::zero_sized(tcx.types.unit),
|
||||
const_: Const::zero_sized(tcx.types.unit),
|
||||
}))),
|
||||
))),
|
||||
});
|
||||
|
|
|
@ -98,10 +98,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
|||
StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))),
|
||||
StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
|
||||
) if lhs_f == lhs_s
|
||||
&& f_c.literal.ty().is_bool()
|
||||
&& s_c.literal.ty().is_bool()
|
||||
&& f_c.literal.try_eval_bool(tcx, param_env).is_some()
|
||||
&& s_c.literal.try_eval_bool(tcx, param_env).is_some() => {}
|
||||
&& f_c.const_.ty().is_bool()
|
||||
&& s_c.const_.ty().is_bool()
|
||||
&& f_c.const_.try_eval_bool(tcx, param_env).is_some()
|
||||
&& s_c.const_.try_eval_bool(tcx, param_env).is_some() => {}
|
||||
|
||||
// Otherwise we cannot optimize. Try another block.
|
||||
_ => continue 'outer,
|
||||
|
@ -128,8 +128,8 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
|||
StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(s_c)))),
|
||||
) => {
|
||||
// From earlier loop we know that we are dealing with bool constants only:
|
||||
let f_b = f_c.literal.try_eval_bool(tcx, param_env).unwrap();
|
||||
let s_b = s_c.literal.try_eval_bool(tcx, param_env).unwrap();
|
||||
let f_b = f_c.const_.try_eval_bool(tcx, param_env).unwrap();
|
||||
let s_b = s_c.const_.try_eval_bool(tcx, param_env).unwrap();
|
||||
if f_b == s_b {
|
||||
// Same value in both blocks. Use statement as is.
|
||||
(*f).clone()
|
||||
|
|
|
@ -90,10 +90,10 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
|
|||
&& let [PlaceElem::Deref] = &place.projection[..]
|
||||
&& let Some(len) = self.slice_lengths[place.local]
|
||||
{
|
||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(Constant {
|
||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::from_ty_const(len, self.tcx),
|
||||
const_: Const::from_ty_const(len, self.tcx),
|
||||
})));
|
||||
}
|
||||
self.super_rvalue(rvalue, loc);
|
||||
|
|
|
@ -62,12 +62,12 @@ impl<'tcx> Replacer<'_, 'tcx> {
|
|||
layout.is_zst()
|
||||
}
|
||||
|
||||
fn make_zst(&self, ty: Ty<'tcx>) -> Constant<'tcx> {
|
||||
fn make_zst(&self, ty: Ty<'tcx>) -> ConstOperand<'tcx> {
|
||||
debug_assert!(self.known_to_be_zst(ty));
|
||||
Constant {
|
||||
ConstOperand {
|
||||
span: rustc_span::DUMMY_SP,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::Val(ConstValue::ZeroSized, ty),
|
||||
const_: Const::Val(ConstValue::ZeroSized, ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{Constant, ConstantKind, Location};
|
||||
use rustc_middle::mir::{Const, ConstOperand, Location};
|
||||
use rustc_middle::ty::ConstKind;
|
||||
|
||||
pub struct RequiredConstsVisitor<'a, 'tcx> {
|
||||
required_consts: &'a mut Vec<Constant<'tcx>>,
|
||||
required_consts: &'a mut Vec<ConstOperand<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
|
||||
pub fn new(required_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
|
||||
pub fn new(required_consts: &'a mut Vec<ConstOperand<'tcx>>) -> Self {
|
||||
RequiredConstsVisitor { required_consts }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
|
||||
let literal = constant.literal;
|
||||
match literal {
|
||||
ConstantKind::Ty(c) => match c.kind() {
|
||||
fn visit_constant(&mut self, constant: &ConstOperand<'tcx>, _: Location) {
|
||||
let const_ = constant.const_;
|
||||
match const_ {
|
||||
Const::Ty(c) => match c.kind() {
|
||||
ConstKind::Param(_) | ConstKind::Error(_) | ConstKind::Value(_) => {}
|
||||
_ => bug!("only ConstKind::Param/Value should be encountered here, got {:#?}", c),
|
||||
},
|
||||
ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
|
||||
ConstantKind::Val(..) => {}
|
||||
Const::Unevaluated(..) => self.required_consts.push(*constant),
|
||||
Const::Val(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,12 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _: Location) {
|
||||
fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
|
||||
// We have to use `try_normalize_erasing_regions` here, since it's
|
||||
// possible that we visit impossible-to-satisfy where clauses here,
|
||||
// see #91745
|
||||
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.literal) {
|
||||
constant.literal = c;
|
||||
if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.const_) {
|
||||
constant.const_ = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -497,10 +497,10 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
|||
|
||||
// `func == Clone::clone(&ty) -> ty`
|
||||
let func_ty = Ty::new_fn_def(tcx, self.def_id, [ty]);
|
||||
let func = Operand::Constant(Box::new(Constant {
|
||||
let func = Operand::Constant(Box::new(ConstOperand {
|
||||
span: self.span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::zero_sized(func_ty),
|
||||
const_: Const::zero_sized(func_ty),
|
||||
}));
|
||||
|
||||
let ref_loc = self.make_place(
|
||||
|
@ -764,10 +764,10 @@ fn build_call_shim<'tcx>(
|
|||
CallKind::Direct(def_id) => {
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
(
|
||||
Operand::Constant(Box::new(Constant {
|
||||
Operand::Constant(Box::new(ConstOperand {
|
||||
span,
|
||||
user_ty: None,
|
||||
literal: ConstantKind::zero_sized(ty),
|
||||
const_: Const::zero_sized(ty),
|
||||
})),
|
||||
rcvr.into_iter().collect::<Vec<_>>(),
|
||||
)
|
||||
|
|
|
@ -23,7 +23,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
|
|||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Constant(ref c), ref targets, ..
|
||||
} => {
|
||||
let constant = c.literal.try_eval_bits(tcx, param_env, c.ty());
|
||||
let constant = c.const_.try_eval_bits(tcx, param_env);
|
||||
if let Some(constant) = constant {
|
||||
let target = targets.target_for_value(constant);
|
||||
TerminatorKind::Goto { target }
|
||||
|
@ -33,7 +33,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
|
|||
}
|
||||
TerminatorKind::Assert {
|
||||
target, cond: Operand::Constant(ref c), expected, ..
|
||||
} => match c.literal.try_eval_bool(tcx, param_env) {
|
||||
} => match c.const_.try_eval_bool(tcx, param_env) {
|
||||
Some(v) if v == expected => TerminatorKind::Goto { target },
|
||||
_ => continue,
|
||||
},
|
||||
|
|
|
@ -206,12 +206,12 @@ fn find_branch_value_info<'tcx>(
|
|||
match (left, right) {
|
||||
(Constant(branch_value), Copy(to_switch_on) | Move(to_switch_on))
|
||||
| (Copy(to_switch_on) | Move(to_switch_on), Constant(branch_value)) => {
|
||||
let branch_value_ty = branch_value.literal.ty();
|
||||
let branch_value_ty = branch_value.const_.ty();
|
||||
// we only want to apply this optimization if we are matching on integrals (and chars), as it is not possible to switch on floats
|
||||
if !branch_value_ty.is_integral() && !branch_value_ty.is_char() {
|
||||
return None;
|
||||
};
|
||||
let branch_value_scalar = branch_value.literal.try_to_scalar()?;
|
||||
let branch_value_scalar = branch_value.const_.try_to_scalar()?;
|
||||
Some((branch_value_scalar, branch_value_ty, *to_switch_on))
|
||||
}
|
||||
_ => None,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue