Get rid of mir::Const::from_ty_const
This commit is contained in:
parent
9a1d156f38
commit
e9a566002d
10 changed files with 21 additions and 98 deletions
|
@ -460,17 +460,6 @@ impl<'tcx> Const<'tcx> {
|
||||||
Self::Val(val, ty)
|
Self::Val(val, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_ty_const(c: ty::Const<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
|
||||||
match c.kind() {
|
|
||||||
ty::ConstKind::Value(ty, valtree) => {
|
|
||||||
// Make sure that if `c` is normalized, then the return value is normalized.
|
|
||||||
let const_val = tcx.valtree_to_const_val((ty, valtree));
|
|
||||||
Self::Val(const_val, ty)
|
|
||||||
}
|
|
||||||
_ => Self::Ty(ty, c),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return true if any evaluation of this constant always returns the same value,
|
/// Return true if any evaluation of this constant always returns the same value,
|
||||||
/// taking into account even pointer identity tests.
|
/// taking into account even pointer identity tests.
|
||||||
pub fn is_deterministic(&self) -> bool {
|
pub fn is_deterministic(&self) -> bool {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use tracing::{debug, instrument};
|
||||||
|
|
||||||
use super::TypingEnv;
|
use super::TypingEnv;
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
|
use crate::mir;
|
||||||
use crate::query::Providers;
|
use crate::query::Providers;
|
||||||
use crate::ty::fold::fold_regions;
|
use crate::ty::fold::fold_regions;
|
||||||
use crate::ty::layout::{FloatExt, IntegerExt};
|
use crate::ty::layout::{FloatExt, IntegerExt};
|
||||||
|
@ -1183,18 +1184,18 @@ impl<'tcx> Ty<'tcx> {
|
||||||
|
|
||||||
/// Returns the maximum value for the given numeric type (including `char`s)
|
/// Returns the maximum value for the given numeric type (including `char`s)
|
||||||
/// or returns `None` if the type is not numeric.
|
/// or returns `None` if the type is not numeric.
|
||||||
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
|
pub fn numeric_max_val(self, tcx: TyCtxt<'tcx>) -> Option<mir::Const<'tcx>> {
|
||||||
let typing_env = TypingEnv::fully_monomorphized();
|
let typing_env = TypingEnv::fully_monomorphized();
|
||||||
self.numeric_min_and_max_as_bits(tcx)
|
self.numeric_min_and_max_as_bits(tcx)
|
||||||
.map(|(_, max)| ty::Const::from_bits(tcx, max, typing_env, self))
|
.map(|(_, max)| mir::Const::from_bits(tcx, max, typing_env, self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the minimum value for the given numeric type (including `char`s)
|
/// Returns the minimum value for the given numeric type (including `char`s)
|
||||||
/// or returns `None` if the type is not numeric.
|
/// or returns `None` if the type is not numeric.
|
||||||
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<ty::Const<'tcx>> {
|
pub fn numeric_min_val(self, tcx: TyCtxt<'tcx>) -> Option<mir::Const<'tcx>> {
|
||||||
let typing_env = TypingEnv::fully_monomorphized();
|
let typing_env = TypingEnv::fully_monomorphized();
|
||||||
self.numeric_min_and_max_as_bits(tcx)
|
self.numeric_min_and_max_as_bits(tcx)
|
||||||
.map(|(min, _)| ty::Const::from_bits(tcx, min, typing_env, self))
|
.map(|(min, _)| mir::Const::from_bits(tcx, min, typing_env, self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether values of this type `T` have a size known at
|
/// Checks whether values of this type `T` have a size known at
|
||||||
|
|
|
@ -1174,11 +1174,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind()
|
) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind()
|
||||||
&& let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() =>
|
&& let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() =>
|
||||||
{
|
{
|
||||||
return self.insert_constant(Const::from_ty_const(
|
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
|
||||||
*len,
|
|
||||||
self.tcx.types.usize,
|
|
||||||
self.tcx,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => Value::UnaryOp(op, arg_index),
|
_ => Value::UnaryOp(op, arg_index),
|
||||||
};
|
};
|
||||||
|
@ -1488,11 +1484,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
// Trivial case: we are fetching a statically known length.
|
// Trivial case: we are fetching a statically known length.
|
||||||
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||||
if let ty::Array(_, len) = place_ty.kind() {
|
if let ty::Array(_, len) = place_ty.kind() {
|
||||||
return self.insert_constant(Const::from_ty_const(
|
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
|
||||||
*len,
|
|
||||||
self.tcx.types.usize,
|
|
||||||
self.tcx,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inner = self.simplify_place_value(place, location)?;
|
let mut inner = self.simplify_place_value(place, location)?;
|
||||||
|
@ -1514,11 +1506,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||||
&& let Some(to) = to.builtin_deref(true)
|
&& let Some(to) = to.builtin_deref(true)
|
||||||
&& let ty::Slice(..) = to.kind()
|
&& let ty::Slice(..) = to.kind()
|
||||||
{
|
{
|
||||||
return self.insert_constant(Const::from_ty_const(
|
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
|
||||||
*len,
|
|
||||||
self.tcx.types.usize,
|
|
||||||
self.tcx,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: a symbolic `Len`.
|
// Fallback: a symbolic `Len`.
|
||||||
|
|
|
@ -167,7 +167,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
|
||||||
if let Rvalue::Len(ref place) = *rvalue {
|
if let Rvalue::Len(ref place) = *rvalue {
|
||||||
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||||
if let ty::Array(_, len) = *place_ty.kind() {
|
if let ty::Array(_, len) = *place_ty.kind() {
|
||||||
let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
|
let const_ = Const::Ty(self.tcx.types.usize, len);
|
||||||
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
|
let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
|
||||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -794,9 +794,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||||
// fictitious values after `{u,i}size::MAX` (see [`IntRange::split`] for why we do
|
// fictitious values after `{u,i}size::MAX` (see [`IntRange::split`] for why we do
|
||||||
// this). We show this to the user as `usize::MAX..` which is slightly incorrect but
|
// this). We show this to the user as `usize::MAX..` which is slightly incorrect but
|
||||||
// probably clear enough.
|
// probably clear enough.
|
||||||
let c = ty.numeric_max_val(cx.tcx).unwrap();
|
lo = PatRangeBoundary::Finite(ty.numeric_max_val(cx.tcx).unwrap());
|
||||||
let value = mir::Const::from_ty_const(c, ty.0, cx.tcx);
|
|
||||||
lo = PatRangeBoundary::Finite(value);
|
|
||||||
}
|
}
|
||||||
let hi = if let Some(hi) = range.hi.minus_one() {
|
let hi = if let Some(hi) = range.hi.minus_one() {
|
||||||
hi
|
hi
|
||||||
|
|
|
@ -451,16 +451,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||||
let ty = ty::Ty::new_static_str(tcx);
|
let ty = ty::Ty::new_static_str(tcx);
|
||||||
let bytes = value.as_bytes();
|
let bytes = value.as_bytes();
|
||||||
let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes);
|
let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes);
|
||||||
|
let val = tcx.valtree_to_const_val((ty, val_tree));
|
||||||
let ct = ty::Const::new_value(tcx, val_tree, ty);
|
mir::Const::from_value(val, ty).stable(&mut tables)
|
||||||
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_const_bool(&self, value: bool) -> MirConst {
|
fn new_const_bool(&self, value: bool) -> MirConst {
|
||||||
let mut tables = self.0.borrow_mut();
|
let mut tables = self.0.borrow_mut();
|
||||||
let ct = ty::Const::from_bool(tables.tcx, value);
|
mir::Const::from_bool(tables.tcx, value).stable(&mut tables)
|
||||||
let ty = tables.tcx.types.bool;
|
|
||||||
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
|
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
|
||||||
|
@ -472,13 +469,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.size;
|
.size;
|
||||||
|
|
||||||
// We don't use Const::from_bits since it doesn't have any error checking.
|
|
||||||
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
|
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
|
||||||
Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
|
Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`."))
|
||||||
})?;
|
})?;
|
||||||
let ct = ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty);
|
Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty)
|
||||||
Ok(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty))
|
.stable(&mut tables))
|
||||||
}
|
}
|
||||||
fn try_new_ty_const_uint(
|
fn try_new_ty_const_uint(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -9,8 +9,6 @@ mod error;
|
||||||
mod mir;
|
mod mir;
|
||||||
mod ty;
|
mod ty;
|
||||||
|
|
||||||
pub(crate) use ty::mir_const_from_ty_const;
|
|
||||||
|
|
||||||
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
|
||||||
type T = stable_mir::mir::Safety;
|
type T = stable_mir::mir::Safety;
|
||||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||||
|
|
|
@ -414,48 +414,6 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mir_const_from_ty_const<'tcx>(
|
|
||||||
tables: &mut Tables<'tcx>,
|
|
||||||
ty_const: ty::Const<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
) -> stable_mir::ty::MirConst {
|
|
||||||
let kind = match ty_const.kind() {
|
|
||||||
ty::ConstKind::Value(ty, val) => {
|
|
||||||
let val = match val {
|
|
||||||
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
|
||||||
ty::ValTree::Branch(branch) => {
|
|
||||||
ty::ValTree::Branch(tables.tcx.lift(branch).unwrap())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let ty = tables.tcx.lift(ty).unwrap();
|
|
||||||
let const_val = tables.tcx.valtree_to_const_val((ty, val));
|
|
||||||
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
|
||||||
stable_mir::ty::ConstantKind::ZeroSized
|
|
||||||
} else {
|
|
||||||
stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation(
|
|
||||||
ty, const_val, tables,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::ConstKind::Param(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)),
|
|
||||||
ty::ConstKind::Error(_) => unreachable!(),
|
|
||||||
ty::ConstKind::Infer(_) => unreachable!(),
|
|
||||||
ty::ConstKind::Bound(_, _) => unimplemented!(),
|
|
||||||
ty::ConstKind::Placeholder(_) => unimplemented!(),
|
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
|
||||||
stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
|
|
||||||
def: tables.const_def(uv.def),
|
|
||||||
args: uv.args.stable(tables),
|
|
||||||
promoted: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ty::ConstKind::Expr(_) => unimplemented!(),
|
|
||||||
};
|
|
||||||
let stable_ty = tables.intern_ty(ty);
|
|
||||||
let id = tables.intern_mir_const(mir::Const::Ty(ty, ty_const));
|
|
||||||
stable_mir::ty::MirConst::new(kind, stable_ty, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
||||||
type T = stable_mir::ty::TyConst;
|
type T = stable_mir::ty::TyConst;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_note;
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
|
use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_middle::mir;
|
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -36,14 +35,12 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
|
||||||
let lhs_const = if let Some(lhs) = lhs {
|
let lhs_const = if let Some(lhs) = lhs {
|
||||||
ConstEvalCtxt::new(cx).eval_pat_expr(lhs)?
|
ConstEvalCtxt::new(cx).eval_pat_expr(lhs)?
|
||||||
} else {
|
} else {
|
||||||
let min_val_const = ty.numeric_min_val(cx.tcx)?;
|
mir_to_const(cx.tcx, ty.numeric_min_val(cx.tcx)?)?
|
||||||
mir_to_const(cx.tcx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
|
|
||||||
};
|
};
|
||||||
let rhs_const = if let Some(rhs) = rhs {
|
let rhs_const = if let Some(rhs) = rhs {
|
||||||
ConstEvalCtxt::new(cx).eval_pat_expr(rhs)?
|
ConstEvalCtxt::new(cx).eval_pat_expr(rhs)?
|
||||||
} else {
|
} else {
|
||||||
let max_val_const = ty.numeric_max_val(cx.tcx)?;
|
mir_to_const(cx.tcx, ty.numeric_max_val(cx.tcx)?)?
|
||||||
mir_to_const(cx.tcx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
|
|
||||||
};
|
};
|
||||||
let lhs_val = lhs_const.int_value(cx.tcx, ty)?;
|
let lhs_val = lhs_const.int_value(cx.tcx, ty)?;
|
||||||
let rhs_val = rhs_const.int_value(cx.tcx, ty)?;
|
let rhs_val = rhs_const.int_value(cx.tcx, ty)?;
|
||||||
|
|
|
@ -112,7 +112,6 @@ use rustc_hir::{
|
||||||
use rustc_lexer::{TokenKind, tokenize};
|
use rustc_lexer::{TokenKind, tokenize};
|
||||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||||
use rustc_middle::hir::place::PlaceBase;
|
use rustc_middle::hir::place::PlaceBase;
|
||||||
use rustc_middle::mir::Const;
|
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||||
use rustc_middle::ty::fast_reject::SimplifiedType;
|
use rustc_middle::ty::fast_reject::SimplifiedType;
|
||||||
use rustc_middle::ty::layout::IntegerExt;
|
use rustc_middle::ty::layout::IntegerExt;
|
||||||
|
@ -1584,8 +1583,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
|
||||||
let start_is_none_or_min = start.is_none_or(|start| {
|
let start_is_none_or_min = start.is_none_or(|start| {
|
||||||
if let rustc_ty::Adt(_, subst) = ty.kind()
|
if let rustc_ty::Adt(_, subst) = ty.kind()
|
||||||
&& let bnd_ty = subst.type_at(0)
|
&& let bnd_ty = subst.type_at(0)
|
||||||
&& let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
|
&& let Some(min_const) = bnd_ty.numeric_min_val(cx.tcx)
|
||||||
&& let Some(min_const) = mir_to_const(cx.tcx, Const::from_ty_const(min_val, bnd_ty, cx.tcx))
|
&& let Some(min_const) = mir_to_const(cx.tcx, min_const)
|
||||||
&& let Some(start_const) = ConstEvalCtxt::new(cx).eval(start)
|
&& let Some(start_const) = ConstEvalCtxt::new(cx).eval(start)
|
||||||
{
|
{
|
||||||
start_const == min_const
|
start_const == min_const
|
||||||
|
@ -1597,8 +1596,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
|
||||||
RangeLimits::Closed => {
|
RangeLimits::Closed => {
|
||||||
if let rustc_ty::Adt(_, subst) = ty.kind()
|
if let rustc_ty::Adt(_, subst) = ty.kind()
|
||||||
&& let bnd_ty = subst.type_at(0)
|
&& let bnd_ty = subst.type_at(0)
|
||||||
&& let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
|
&& let Some(max_const) = bnd_ty.numeric_max_val(cx.tcx)
|
||||||
&& let Some(max_const) = mir_to_const(cx.tcx, Const::from_ty_const(max_val, bnd_ty, cx.tcx))
|
&& let Some(max_const) = mir_to_const(cx.tcx, max_const)
|
||||||
&& let Some(end_const) = ConstEvalCtxt::new(cx).eval(end)
|
&& let Some(end_const) = ConstEvalCtxt::new(cx).eval(end)
|
||||||
{
|
{
|
||||||
end_const == max_const
|
end_const == max_const
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue