Add Ty
to mir::Const::Ty
This commit is contained in:
parent
8d6705cdb8
commit
60a5bebbe5
19 changed files with 81 additions and 51 deletions
|
@ -204,7 +204,9 @@ pub enum Const<'tcx> {
|
|||
/// Any way of turning `ty::Const` into `ConstValue` should go through `valtree_to_const_val`;
|
||||
/// this ensures that we consistently produce "clean" values without data in the padding or
|
||||
/// anything like that.
|
||||
Ty(ty::Const<'tcx>),
|
||||
///
|
||||
/// FIXME(BoxyUwU): We should remove this `Ty` and look up the type for params via `ParamEnv`
|
||||
Ty(Ty<'tcx>, ty::Const<'tcx>),
|
||||
|
||||
/// An unevaluated mir constant which is not part of the type system.
|
||||
///
|
||||
|
@ -237,8 +239,15 @@ impl<'tcx> Const<'tcx> {
|
|||
#[inline(always)]
|
||||
pub fn ty(&self) -> Ty<'tcx> {
|
||||
match self {
|
||||
// THISPR
|
||||
Const::Ty(c) => todo!(),
|
||||
Const::Ty(ty, ct) => {
|
||||
match ct.kind() {
|
||||
// Dont use the outter ty as on invalid code we can wind up with them not being the same.
|
||||
// this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
|
||||
// was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
|
||||
ty::ConstKind::Value(ty, _) => ty,
|
||||
_ => *ty,
|
||||
}
|
||||
}
|
||||
Const::Val(_, ty) | Const::Unevaluated(_, ty) => *ty,
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +257,7 @@ impl<'tcx> Const<'tcx> {
|
|||
#[inline]
|
||||
pub fn is_required_const(&self) -> bool {
|
||||
match self {
|
||||
Const::Ty(c) => match c.kind() {
|
||||
Const::Ty(_, c) => match c.kind() {
|
||||
ty::ConstKind::Value(_, _) => false, // already a value, cannot error
|
||||
_ => true,
|
||||
},
|
||||
|
@ -260,7 +269,7 @@ impl<'tcx> Const<'tcx> {
|
|||
#[inline]
|
||||
pub fn try_to_scalar(self) -> Option<Scalar> {
|
||||
match self {
|
||||
Const::Ty(c) => match c.kind() {
|
||||
Const::Ty(_, c) => match c.kind() {
|
||||
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
|
||||
// A valtree of a type where leaves directly represent the scalar const value.
|
||||
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
|
||||
|
@ -279,7 +288,7 @@ impl<'tcx> Const<'tcx> {
|
|||
// This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
|
||||
match self {
|
||||
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
|
||||
Const::Ty(c) => match c.kind() {
|
||||
Const::Ty(_, c) => match c.kind() {
|
||||
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
|
||||
Some(valtree.unwrap_leaf())
|
||||
}
|
||||
|
@ -307,7 +316,7 @@ impl<'tcx> Const<'tcx> {
|
|||
span: Span,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self {
|
||||
Const::Ty(c) => {
|
||||
Const::Ty(_, c) => {
|
||||
// We want to consistently have a "clean" value for type system constants (i.e., no
|
||||
// data hidden in the padding), so we always go through a valtree here.
|
||||
let (ty, val) = c.eval(tcx, param_env, span)?;
|
||||
|
@ -327,7 +336,7 @@ impl<'tcx> Const<'tcx> {
|
|||
match self.eval(tcx, param_env, DUMMY_SP) {
|
||||
Ok(val) => Self::Val(val, self.ty()),
|
||||
Err(ErrorHandled::Reported(guar, _span)) => {
|
||||
Self::Ty(ty::Const::new_error(tcx, guar.into()))
|
||||
Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into()))
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(_span)) => self,
|
||||
}
|
||||
|
@ -339,7 +348,7 @@ impl<'tcx> Const<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<Scalar> {
|
||||
if let Const::Ty(c) = self
|
||||
if let Const::Ty(_, c) = self
|
||||
&& let ty::ConstKind::Value(ty, val) = c.kind()
|
||||
&& ty.is_primitive()
|
||||
{
|
||||
|
@ -441,14 +450,14 @@ impl<'tcx> Const<'tcx> {
|
|||
Self::Val(val, ty)
|
||||
}
|
||||
|
||||
pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
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(c),
|
||||
_ => Self::Ty(ty, c),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,7 +469,7 @@ impl<'tcx> Const<'tcx> {
|
|||
// - valtrees purposefully generate new allocations
|
||||
// - ConstValue::Slice also generate new allocations
|
||||
match self {
|
||||
Const::Ty(c) => match c.kind() {
|
||||
Const::Ty(_, c) => match c.kind() {
|
||||
ty::ConstKind::Param(..) => true,
|
||||
// A valtree may be a reference. Valtree references correspond to a
|
||||
// different allocation each time they are evaluated. Valtrees for primitive
|
||||
|
@ -519,7 +528,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
|
|||
impl<'tcx> Display for Const<'tcx> {
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
Const::Ty(c) => pretty_print_const(c, fmt, true),
|
||||
Const::Ty(_, c) => pretty_print_const(c, fmt, true),
|
||||
Const::Val(val, ty) => pretty_print_const_value(val, ty, fmt),
|
||||
// FIXME(valtrees): Correctly print mir constants.
|
||||
Const::Unevaluated(c, _ty) => {
|
||||
|
|
|
@ -1313,7 +1313,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
|||
};
|
||||
|
||||
let val = match const_ {
|
||||
Const::Ty(ct) => match ct.kind() {
|
||||
Const::Ty(_, ct) => match ct.kind() {
|
||||
ty::ConstKind::Param(p) => format!("ty::Param({p})"),
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
|
||||
|
@ -1417,7 +1417,7 @@ pub fn write_allocations<'tcx>(
|
|||
impl<'tcx> Visitor<'tcx> for CollectAllocIds {
|
||||
fn visit_constant(&mut self, c: &ConstOperand<'tcx>, _: Location) {
|
||||
match c.const_ {
|
||||
Const::Ty(_) | Const::Unevaluated(..) => {}
|
||||
Const::Ty(_, _) | Const::Unevaluated(..) => {}
|
||||
Const::Val(val, _) => {
|
||||
self.0.extend(alloc_ids_from_const_val(val));
|
||||
}
|
||||
|
|
|
@ -895,7 +895,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
self.visit_span($(& $mutability)? *span);
|
||||
match const_ {
|
||||
Const::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
|
||||
Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location),
|
||||
Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||
Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue