Clean up the ty::Const::assert*
methods
This commit is contained in:
parent
4be0675589
commit
437f017e2e
6 changed files with 30 additions and 50 deletions
|
@ -2368,7 +2368,7 @@ impl<'tcx> AdtDef {
|
||||||
match tcx.const_eval(param_env.and(cid)) {
|
match tcx.const_eval(param_env.and(cid)) {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
// FIXME: Find the right type and use it instead of `val.ty` here
|
// FIXME: Find the right type and use it instead of `val.ty` here
|
||||||
if let Some(b) = val.assert_bits(tcx.global_tcx(), param_env.and(val.ty)) {
|
if let Some(b) = val.assert_bits(tcx.global_tcx(), val.ty) {
|
||||||
trace!("discriminants: {} ({:?})", b, repr_type);
|
trace!("discriminants: {} ({:?})", b, repr_type);
|
||||||
Some(Discr {
|
Some(Discr {
|
||||||
val: b,
|
val: b,
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFolda
|
||||||
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
|
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
|
||||||
use crate::ty::layout::VariantIdx;
|
use crate::ty::layout::VariantIdx;
|
||||||
use crate::util::captures::Captures;
|
use crate::util::captures::Captures;
|
||||||
use crate::mir::interpret::{Scalar, Pointer};
|
use crate::mir::interpret::Scalar;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -2291,29 +2291,16 @@ impl<'tcx> Const<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
|
pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<u128> {
|
||||||
if self.ty != ty.value {
|
assert_eq!(self.ty, ty);
|
||||||
return None;
|
let ty = tcx.lift_to_global(&ty).unwrap();
|
||||||
}
|
let size = tcx.layout_of(ParamEnv::empty().and(ty)).ok()?.size;
|
||||||
let size = tcx.layout_of(ty).ok()?.size;
|
|
||||||
self.val.try_to_bits(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn to_ptr(&self) -> Option<Pointer> {
|
|
||||||
self.val.try_to_ptr()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
|
|
||||||
assert_eq!(self.ty, ty.value);
|
|
||||||
let size = tcx.layout_of(ty).ok()?.size;
|
|
||||||
self.val.try_to_bits(size)
|
self.val.try_to_bits(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
|
pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
|
||||||
self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
|
self.assert_bits(tcx, tcx.types.bool).and_then(|v| match v {
|
||||||
0 => Some(false),
|
0 => Some(false),
|
||||||
1 => Some(true),
|
1 => Some(true),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -2322,19 +2309,18 @@ impl<'tcx> Const<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
|
||||||
self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
|
self.assert_bits(tcx, tcx.types.usize).map(|v| v as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
|
pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> u128 {
|
||||||
self.assert_bits(tcx, ty).unwrap_or_else(||
|
self.assert_bits(tcx, ty).unwrap_or_else(||
|
||||||
bug!("expected bits of {}, got {:#?}", ty.value, self))
|
bug!("expected bits of {}, got {:#?}", ty, self))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
|
pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
|
||||||
self.assert_usize(tcx).unwrap_or_else(||
|
self.unwrap_bits(tcx, tcx.types.usize) as u64
|
||||||
bug!("expected constant usize, got {:#?}", self))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
match *match_pair.pattern.kind {
|
match *match_pair.pattern.kind {
|
||||||
PatternKind::Constant { value } => {
|
PatternKind::Constant { value } => {
|
||||||
let switch_ty = ty::ParamEnv::empty().and(switch_ty);
|
|
||||||
indices.entry(value)
|
indices.entry(value)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
|
options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
|
||||||
|
@ -653,11 +652,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
use std::cmp::Ordering::*;
|
use std::cmp::Ordering::*;
|
||||||
use rustc::hir::RangeEnd::*;
|
use rustc::hir::RangeEnd::*;
|
||||||
|
|
||||||
let param_env = ty::ParamEnv::empty().and(test.ty);
|
|
||||||
let tcx = self.hir.tcx();
|
let tcx = self.hir.tcx();
|
||||||
|
|
||||||
let lo = compare_const_vals(tcx, test.lo, pat.hi, param_env)?;
|
let lo = compare_const_vals(tcx, test.lo, pat.hi, test.ty)?;
|
||||||
let hi = compare_const_vals(tcx, test.hi, pat.lo, param_env)?;
|
let hi = compare_const_vals(tcx, test.hi, pat.lo, test.ty)?;
|
||||||
|
|
||||||
match (test.end, pat.end, lo, hi) {
|
match (test.end, pat.end, lo, hi) {
|
||||||
// pat < test
|
// pat < test
|
||||||
|
@ -772,11 +770,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
) -> Option<bool> {
|
) -> Option<bool> {
|
||||||
use std::cmp::Ordering::*;
|
use std::cmp::Ordering::*;
|
||||||
|
|
||||||
let param_env = ty::ParamEnv::empty().and(range.ty);
|
|
||||||
let tcx = self.hir.tcx();
|
let tcx = self.hir.tcx();
|
||||||
|
|
||||||
let a = compare_const_vals(tcx, range.lo, value, param_env)?;
|
let a = compare_const_vals(tcx, range.lo, value, range.ty)?;
|
||||||
let b = compare_const_vals(tcx, value, range.hi, param_env)?;
|
let b = compare_const_vals(tcx, value, range.hi, range.ty)?;
|
||||||
|
|
||||||
match (b, range.end) {
|
match (b, range.end) {
|
||||||
(Less, _) |
|
(Less, _) |
|
||||||
|
|
|
@ -856,7 +856,7 @@ impl<'tcx> IntRange<'tcx> {
|
||||||
}
|
}
|
||||||
ConstantValue(val) if is_integral(val.ty) => {
|
ConstantValue(val) if is_integral(val.ty) => {
|
||||||
let ty = val.ty;
|
let ty = val.ty;
|
||||||
if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
|
if let Some(val) = val.assert_bits(tcx, ty) {
|
||||||
let bias = IntRange::signed_bias(tcx, ty);
|
let bias = IntRange::signed_bias(tcx, ty);
|
||||||
let val = val ^ bias;
|
let val = val ^ bias;
|
||||||
Some(IntRange { range: val..=val, ty })
|
Some(IntRange { range: val..=val, ty })
|
||||||
|
@ -873,8 +873,8 @@ impl<'tcx> IntRange<'tcx> {
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
box PatternKind::Constant { value } => break ConstantValue(value),
|
box PatternKind::Constant { value } => break ConstantValue(value),
|
||||||
box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
|
box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
|
||||||
lo.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
|
lo.unwrap_bits(tcx, ty),
|
||||||
hi.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
|
hi.unwrap_bits(tcx, ty),
|
||||||
ty,
|
ty,
|
||||||
end,
|
end,
|
||||||
),
|
),
|
||||||
|
@ -1327,8 +1327,8 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
|
||||||
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
|
PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
|
||||||
PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
|
PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
|
||||||
Some(vec![ConstantRange(
|
Some(vec![ConstantRange(
|
||||||
lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
|
lo.unwrap_bits(cx.tcx, ty),
|
||||||
hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
|
hi.unwrap_bits(cx.tcx, ty),
|
||||||
ty,
|
ty,
|
||||||
end,
|
end,
|
||||||
)]),
|
)]),
|
||||||
|
@ -1464,7 +1464,7 @@ fn slice_pat_covered_by_const<'tcx>(
|
||||||
{
|
{
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
box PatternKind::Constant { value } => {
|
box PatternKind::Constant { value } => {
|
||||||
let b = value.unwrap_bits(tcx, ty::ParamEnv::empty().and(pat.ty));
|
let b = value.unwrap_bits(tcx, pat.ty);
|
||||||
assert_eq!(b as u8 as u128, b);
|
assert_eq!(b as u8 as u128, b);
|
||||||
if b as u8 != *ch {
|
if b as u8 != *ch {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
|
@ -1641,9 +1641,9 @@ fn constructor_covered_by_range<'tcx>(
|
||||||
_ => bug!("`constructor_covered_by_range` called with {:?}", pat),
|
_ => bug!("`constructor_covered_by_range` called with {:?}", pat),
|
||||||
};
|
};
|
||||||
trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
|
trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
|
||||||
let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, ty::ParamEnv::empty().and(ty))
|
let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, ty)
|
||||||
.map(|res| res != Ordering::Less);
|
.map(|res| res != Ordering::Less);
|
||||||
let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, ty::ParamEnv::empty().and(ty));
|
let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, ty);
|
||||||
macro_rules! some_or_ok {
|
macro_rules! some_or_ok {
|
||||||
($e:expr) => {
|
($e:expr) => {
|
||||||
match $e {
|
match $e {
|
||||||
|
|
|
@ -446,7 +446,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||||
self.tcx,
|
self.tcx,
|
||||||
lo,
|
lo,
|
||||||
hi,
|
hi,
|
||||||
self.param_env.and(ty),
|
ty,
|
||||||
);
|
);
|
||||||
match (end, cmp) {
|
match (end, cmp) {
|
||||||
(RangeEnd::Excluded, Some(Ordering::Less)) =>
|
(RangeEnd::Excluded, Some(Ordering::Less)) =>
|
||||||
|
@ -1451,7 +1451,7 @@ pub fn compare_const_vals<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
a: &'tcx ty::Const<'tcx>,
|
a: &'tcx ty::Const<'tcx>,
|
||||||
b: &'tcx ty::Const<'tcx>,
|
b: &'tcx ty::Const<'tcx>,
|
||||||
ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
ty: Ty<'tcx>,
|
||||||
) -> Option<Ordering> {
|
) -> Option<Ordering> {
|
||||||
trace!("compare_const_vals: {:?}, {:?}", a, b);
|
trace!("compare_const_vals: {:?}, {:?}", a, b);
|
||||||
|
|
||||||
|
@ -1466,15 +1466,13 @@ pub fn compare_const_vals<'tcx>(
|
||||||
let fallback = || from_bool(a == b);
|
let fallback = || from_bool(a == b);
|
||||||
|
|
||||||
// Use the fallback if any type differs
|
// Use the fallback if any type differs
|
||||||
if a.ty != b.ty || a.ty != ty.value {
|
if a.ty != b.ty || a.ty != ty {
|
||||||
return fallback();
|
return fallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This should use assert_bits(ty) instead of use_bits
|
if let (Some(a), Some(b)) = (a.assert_bits(tcx, ty), b.assert_bits(tcx, ty)) {
|
||||||
// but triggers possibly bugs due to mismatching of arrays and slices
|
|
||||||
if let (Some(a), Some(b)) = (a.to_bits(tcx, ty), b.to_bits(tcx, ty)) {
|
|
||||||
use ::rustc_apfloat::Float;
|
use ::rustc_apfloat::Float;
|
||||||
return match ty.value.sty {
|
return match ty.sty {
|
||||||
ty::Float(ast::FloatTy::F32) => {
|
ty::Float(ast::FloatTy::F32) => {
|
||||||
let l = ::rustc_apfloat::ieee::Single::from_bits(a);
|
let l = ::rustc_apfloat::ieee::Single::from_bits(a);
|
||||||
let r = ::rustc_apfloat::ieee::Single::from_bits(b);
|
let r = ::rustc_apfloat::ieee::Single::from_bits(b);
|
||||||
|
@ -1497,7 +1495,7 @@ pub fn compare_const_vals<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ty::Str = ty.value.sty {
|
if let ty::Str = ty.sty {
|
||||||
match (a.val, b.val) {
|
match (a.val, b.val) {
|
||||||
(
|
(
|
||||||
ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
|
ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! A pass that simplifies branches when their condition is known.
|
//! A pass that simplifies branches when their condition is known.
|
||||||
|
|
||||||
use rustc::ty::{TyCtxt, ParamEnv};
|
use rustc::ty::TyCtxt;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use crate::transform::{MirPass, MirSource};
|
use crate::transform::{MirPass, MirSource};
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ impl MirPass for SimplifyBranches {
|
||||||
TerminatorKind::SwitchInt {
|
TerminatorKind::SwitchInt {
|
||||||
discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
|
discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
|
||||||
} => {
|
} => {
|
||||||
let switch_ty = ParamEnv::empty().and(switch_ty);
|
|
||||||
let constant = c.literal.assert_bits(tcx, switch_ty);
|
let constant = c.literal.assert_bits(tcx, switch_ty);
|
||||||
if let Some(constant) = constant {
|
if let Some(constant) = constant {
|
||||||
let (otherwise, targets) = targets.split_last().unwrap();
|
let (otherwise, targets) = targets.split_last().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue