1
Fork 0

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:
Guillaume Gomez 2023-09-21 13:25:39 +02:00 committed by GitHub
commit 208f6ed95c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 461 additions and 493 deletions

View file

@ -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,

View file

@ -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 {

View file

@ -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),

View file

@ -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,

View file

@ -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) {

View file

@ -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);

View file

@ -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))
}
}

View file

@ -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);

View file

@ -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),
})))
}

View file

@ -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),

View file

@ -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

View file

@ -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)));
}
}

View file

@ -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,
),

View file

@ -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) =>
{

View file

@ -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),
}))),
))),
});

View file

@ -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()

View file

@ -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);

View file

@ -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),
}
}
}

View file

@ -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(..) => {}
}
}
}

View file

@ -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;
}
}

View file

@ -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<_>>(),
)

View file

@ -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,
},

View file

@ -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,