Skip to content

Commit

Permalink
Auto merge of rust-lang#135753 - compiler-errors:from-ty-const, r=oli…
Browse files Browse the repository at this point in the history
…-obk

Get rid of `mir::Const::from_ty_const`

This function is strange, because it turns valtrees into `mir::Const::Value`, but the rest of the const variants stay as type system consts.

All of the callsites except for one in `instsimplify` (array length simplification of `ptr_metadata` call) just go through the valtree arm of the function, so it's easier to just create a `mir::Const` directly for those.

For the instsimplify case, if we have a type system const we should *keep* having a type system const, rather than turning it into a `mir::Const::Value`; it doesn't really matter in practice, though, bc `usize` has no padding, but it feels more principled.
  • Loading branch information
bors committed Jan 26, 2025
2 parents c2270be + e9a5660 commit d9b4598
Show file tree
Hide file tree
Showing 10 changed files with 21 additions and 98 deletions.
11 changes: 0 additions & 11 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,17 +460,6 @@ impl<'tcx> Const<'tcx> {
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,
/// taking into account even pointer identity tests.
pub fn is_deterministic(&self) -> bool {
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use tracing::{debug, instrument};

use super::TypingEnv;
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
use crate::query::Providers;
use crate::ty::fold::fold_regions;
use crate::ty::layout::{FloatExt, IntegerExt};
Expand Down Expand Up @@ -1183,18 +1184,18 @@ impl<'tcx> Ty<'tcx> {

/// Returns the maximum value for the given numeric type (including `char`s)
/// 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();
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)
/// 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();
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
Expand Down
18 changes: 3 additions & 15 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1178,11 +1178,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
) if let ty::Slice(..) = to.builtin_deref(true).unwrap().kind()
&& let ty::Array(_, len) = from.builtin_deref(true).unwrap().kind() =>
{
return self.insert_constant(Const::from_ty_const(
*len,
self.tcx.types.usize,
self.tcx,
));
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
}
_ => Value::UnaryOp(op, arg_index),
};
Expand Down Expand Up @@ -1492,11 +1488,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
// Trivial case: we are fetching a statically known length.
let place_ty = place.ty(self.local_decls, self.tcx).ty;
if let ty::Array(_, len) = place_ty.kind() {
return self.insert_constant(Const::from_ty_const(
*len,
self.tcx.types.usize,
self.tcx,
));
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
}

let mut inner = self.simplify_place_value(place, location)?;
Expand All @@ -1518,11 +1510,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
&& let Some(to) = to.builtin_deref(true)
&& let ty::Slice(..) = to.kind()
{
return self.insert_constant(Const::from_ty_const(
*len,
self.tcx.types.usize,
self.tcx,
));
return self.insert_constant(Const::Ty(self.tcx.types.usize, *len));
}

// Fallback: a symbolic `Len`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/instsimplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
if let Rvalue::Len(ref place) = *rvalue {
let place_ty = place.ty(self.local_decls, self.tcx).ty;
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 };
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_pattern_analysis/src/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// this). We show this to the user as `usize::MAX..` which is slightly incorrect but
// probably clear enough.
let c = ty.numeric_max_val(cx.tcx).unwrap();
let value = mir::Const::from_ty_const(c, ty.0, cx.tcx);
lo = PatRangeBoundary::Finite(value);
lo = PatRangeBoundary::Finite(ty.numeric_max_val(cx.tcx).unwrap());
}
let hi = if let Some(hi) = range.hi.minus_one() {
hi
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_smir/src/rustc_smir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,16 +451,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
let ty = ty::Ty::new_static_str(tcx);
let bytes = value.as_bytes();
let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes);

let ct = ty::Const::new_value(tcx, val_tree, ty);
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
let val = tcx.valtree_to_const_val((ty, val_tree));
mir::Const::from_value(val, ty).stable(&mut tables)
}

fn new_const_bool(&self, value: bool) -> MirConst {
let mut tables = self.0.borrow_mut();
let ct = ty::Const::from_bool(tables.tcx, value);
let ty = tables.tcx.types.bool;
super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)
mir::Const::from_bool(tables.tcx, value).stable(&mut tables)
}

fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
Expand All @@ -472,13 +469,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
.unwrap()
.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(|| {
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(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty))
Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty)
.stable(&mut tables))
}
fn try_new_ty_const_uint(
&self,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_smir/src/rustc_smir/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ mod error;
mod mir;
mod ty;

pub(crate) use ty::mir_const_from_ty_const;

impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
type T = stable_mir::mir::Safety;
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
Expand Down
42 changes: 0 additions & 42 deletions compiler/rustc_smir/src/rustc_smir/convert/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
type T = stable_mir::ty::TyConst;

Expand Down
7 changes: 2 additions & 5 deletions src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_note;
use core::cmp::Ordering;
use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
use rustc_lint::LateContext;
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_span::Span;

Expand Down Expand Up @@ -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 {
ConstEvalCtxt::new(cx).eval_pat_expr(lhs)?
} else {
let min_val_const = ty.numeric_min_val(cx.tcx)?;
mir_to_const(cx.tcx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
mir_to_const(cx.tcx, ty.numeric_min_val(cx.tcx)?)?
};
let rhs_const = if let Some(rhs) = rhs {
ConstEvalCtxt::new(cx).eval_pat_expr(rhs)?
} else {
let max_val_const = ty.numeric_max_val(cx.tcx)?;
mir_to_const(cx.tcx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
mir_to_const(cx.tcx, ty.numeric_max_val(cx.tcx)?)?
};
let lhs_val = lhs_const.int_value(cx.tcx, ty)?;
let rhs_val = rhs_const.int_value(cx.tcx, ty)?;
Expand Down
9 changes: 4 additions & 5 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ use rustc_hir::{
use rustc_lexer::{TokenKind, tokenize};
use rustc_lint::{LateContext, Level, Lint, LintContext};
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::mir::Const;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::layout::IntegerExt;
Expand Down Expand Up @@ -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| {
if let rustc_ty::Adt(_, subst) = ty.kind()
&& let bnd_ty = subst.type_at(0)
&& let Some(min_val) = 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) = bnd_ty.numeric_min_val(cx.tcx)
&& let Some(min_const) = mir_to_const(cx.tcx, min_const)
&& let Some(start_const) = ConstEvalCtxt::new(cx).eval(start)
{
start_const == min_const
Expand All @@ -1597,8 +1596,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
RangeLimits::Closed => {
if let rustc_ty::Adt(_, subst) = ty.kind()
&& let bnd_ty = subst.type_at(0)
&& let Some(max_val) = 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) = bnd_ty.numeric_max_val(cx.tcx)
&& let Some(max_const) = mir_to_const(cx.tcx, max_const)
&& let Some(end_const) = ConstEvalCtxt::new(cx).eval(end)
{
end_const == max_const
Expand Down

0 comments on commit d9b4598

Please sign in to comment.