mirror of https://github.com/rust-lang/rust.git
Add `Ty` to `ConstKind::Value`
This commit is contained in:
parent
58feec9b85
commit
a9702a6668
|
@ -1201,6 +1201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||||
.expect_const()
|
.expect_const()
|
||||||
.eval(tcx, ty::ParamEnv::reveal_all(), span)
|
.eval(tcx, ty::ParamEnv::reveal_all(), span)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
.1
|
||||||
.unwrap_branch();
|
.unwrap_branch();
|
||||||
let n = idx.len() as u64;
|
let n = idx.len() as u64;
|
||||||
|
|
||||||
|
|
|
@ -693,42 +693,46 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
|
||||||
ty::ConstKind::Param(param) => {
|
ty::ConstKind::Param(param) => {
|
||||||
write!(output, "{}", param.name)
|
write!(output, "{}", param.name)
|
||||||
}
|
}
|
||||||
// THISPR
|
ty::ConstKind::Value(ty, _) => {
|
||||||
_ => match { todo!() as Ty<'tcx> }.kind() {
|
match ty.kind() {
|
||||||
ty::Int(ity) => {
|
ty::Int(ity) => {
|
||||||
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
|
// FIXME: directly extract the bits from a valtree instead of evaluating an
|
||||||
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
|
// alreay evaluated `Const` in order to get the bits.
|
||||||
write!(output, "{val}")
|
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
|
||||||
}
|
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
|
||||||
ty::Uint(_) => {
|
write!(output, "{val}")
|
||||||
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
|
}
|
||||||
write!(output, "{val}")
|
ty::Uint(_) => {
|
||||||
}
|
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
|
||||||
ty::Bool => {
|
write!(output, "{val}")
|
||||||
let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
|
}
|
||||||
write!(output, "{val}")
|
ty::Bool => {
|
||||||
}
|
let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
|
||||||
_ => {
|
write!(output, "{val}")
|
||||||
// If we cannot evaluate the constant to a known type, we fall back
|
}
|
||||||
// to emitting a stable hash value of the constant. This isn't very pretty
|
_ => {
|
||||||
// but we get a deterministic, virtually unique value for the constant.
|
// If we cannot evaluate the constant to a known type, we fall back
|
||||||
//
|
// to emitting a stable hash value of the constant. This isn't very pretty
|
||||||
// Let's only emit 64 bits of the hash value. That should be plenty for
|
// but we get a deterministic, virtually unique value for the constant.
|
||||||
// avoiding collisions and will make the emitted type names shorter.
|
//
|
||||||
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
|
// Let's only emit 64 bits of the hash value. That should be plenty for
|
||||||
let mut hasher = StableHasher::new();
|
// avoiding collisions and will make the emitted type names shorter.
|
||||||
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
|
let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
|
||||||
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
|
let mut hasher = StableHasher::new();
|
||||||
hasher.finish::<Hash64>()
|
let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
|
||||||
});
|
hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
|
||||||
|
hasher.finish::<Hash64>()
|
||||||
|
});
|
||||||
|
|
||||||
if cpp_like_debuginfo(tcx) {
|
if cpp_like_debuginfo(tcx) {
|
||||||
write!(output, "CONST${hash_short:x}")
|
write!(output, "CONST${hash_short:x}")
|
||||||
} else {
|
} else {
|
||||||
write!(output, "{{CONST#{hash_short:x}}}")
|
write!(output, "{{CONST#{hash_short:x}}}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
_ => bug!("Invalid `Const` during codegen: {:?}", ct),
|
||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
mir::Const::Ty(c) => match c.kind() {
|
mir::Const::Ty(c) => match c.kind() {
|
||||||
// A constant that came from a const generic but was then used as an argument to old-style
|
// A constant that came from a const generic but was then used as an argument to old-style
|
||||||
// simd_shuffle (passing as argument instead of as a generic param).
|
// simd_shuffle (passing as argument instead of as a generic param).
|
||||||
rustc_type_ir::ConstKind::Value(valtree) => return Ok(Some(valtree)),
|
rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)),
|
||||||
other => span_bug!(constant.span, "{other:#?}"),
|
other => span_bug!(constant.span, "{other:#?}"),
|
||||||
},
|
},
|
||||||
// We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
|
// We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
|
||||||
|
|
|
@ -360,7 +360,7 @@ where
|
||||||
Const::Ty(ct)
|
Const::Ty(ct)
|
||||||
if matches!(
|
if matches!(
|
||||||
ct.kind(),
|
ct.kind(),
|
||||||
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_)
|
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _)
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
None
|
None
|
||||||
|
|
|
@ -2409,7 +2409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
min_len: u64,
|
min_len: u64,
|
||||||
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
|
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
|
||||||
let len = match len.eval(self.tcx, self.param_env, span) {
|
let len = match len.eval(self.tcx, self.param_env, span) {
|
||||||
Ok(val) => val
|
// FIXME(BoxyUwU): Assert the `Ty` is a `usize`?
|
||||||
|
Ok((_, val)) => val
|
||||||
.try_to_scalar()
|
.try_to_scalar()
|
||||||
.and_then(|scalar| scalar.try_to_int().ok())
|
.and_then(|scalar| scalar.try_to_int().ok())
|
||||||
.and_then(|int| int.try_to_target_usize(self.tcx).ok()),
|
.and_then(|int| int.try_to_target_usize(self.tcx).ok()),
|
||||||
|
|
|
@ -176,7 +176,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ConstKind::Param(_)
|
ty::ConstKind::Param(_)
|
||||||
| ty::ConstKind::Value(_)
|
| ty::ConstKind::Value(_, _)
|
||||||
| ty::ConstKind::Unevaluated(..)
|
| ty::ConstKind::Unevaluated(..)
|
||||||
| ty::ConstKind::Expr(..)
|
| ty::ConstKind::Expr(..)
|
||||||
| ty::ConstKind::Error(_) => ct.super_fold_with(self),
|
| ty::ConstKind::Error(_) => ct.super_fold_with(self),
|
||||||
|
|
|
@ -1299,7 +1299,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
| ty::ConstKind::Bound(_, _)
|
| ty::ConstKind::Bound(_, _)
|
||||||
| ty::ConstKind::Placeholder(_)
|
| ty::ConstKind::Placeholder(_)
|
||||||
| ty::ConstKind::Unevaluated(_)
|
| ty::ConstKind::Unevaluated(_)
|
||||||
| ty::ConstKind::Value(_)
|
| ty::ConstKind::Value(_, _)
|
||||||
| ty::ConstKind::Error(_)
|
| ty::ConstKind::Error(_)
|
||||||
| ty::ConstKind::Expr(_) => ct,
|
| ty::ConstKind::Expr(_) => ct,
|
||||||
}
|
}
|
||||||
|
@ -1514,8 +1514,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ty::Const<'tcx>, ErrorHandled> {
|
) -> Result<ty::Const<'tcx>, ErrorHandled> {
|
||||||
match self.const_eval_resolve(param_env, unevaluated, span) {
|
match self.const_eval_resolve(param_env, unevaluated, span) {
|
||||||
// THISPR
|
Ok(Some(val)) => Ok(ty::Const::new_value(
|
||||||
Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, todo!())),
|
self.tcx,
|
||||||
|
val,
|
||||||
|
self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args),
|
||||||
|
)),
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let def_id = unevaluated.def;
|
let def_id = unevaluated.def;
|
||||||
|
|
|
@ -249,7 +249,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
pub fn is_required_const(&self) -> bool {
|
pub fn is_required_const(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Const::Ty(c) => match c.kind() {
|
Const::Ty(c) => match c.kind() {
|
||||||
ty::ConstKind::Value(_) => false, // already a value, cannot error
|
ty::ConstKind::Value(_, _) => false, // already a value, cannot error
|
||||||
_ => true,
|
_ => true,
|
||||||
},
|
},
|
||||||
Const::Val(..) => false, // already a value, cannot error
|
Const::Val(..) => false, // already a value, cannot error
|
||||||
|
@ -261,9 +261,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
pub fn try_to_scalar(self) -> Option<Scalar> {
|
pub fn try_to_scalar(self) -> Option<Scalar> {
|
||||||
match self {
|
match self {
|
||||||
Const::Ty(c) => match c.kind() {
|
Const::Ty(c) => match c.kind() {
|
||||||
// THISPR
|
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
|
||||||
// if c.ty().is_primitive()
|
|
||||||
ty::ConstKind::Value(valtree) if todo!() => {
|
|
||||||
// A valtree of a type where leaves directly represent the scalar const value.
|
// 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
|
// Just checking whether it is a leaf is insufficient as e.g. references are leafs
|
||||||
// but the leaf value is the value they point to, not the reference itself!
|
// but the leaf value is the value they point to, not the reference itself!
|
||||||
|
@ -282,9 +280,9 @@ impl<'tcx> Const<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
|
Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
|
||||||
Const::Ty(c) => match c.kind() {
|
Const::Ty(c) => match c.kind() {
|
||||||
// THISPR
|
ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
|
||||||
// if c.ty().is_primitive()
|
Some(valtree.unwrap_leaf())
|
||||||
ty::ConstKind::Value(valtree) if todo!() => Some(valtree.unwrap_leaf()),
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -312,8 +310,8 @@ impl<'tcx> Const<'tcx> {
|
||||||
Const::Ty(c) => {
|
Const::Ty(c) => {
|
||||||
// We want to consistently have a "clean" value for type system constants (i.e., no
|
// 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.
|
// data hidden in the padding), so we always go through a valtree here.
|
||||||
let val = c.eval(tcx, param_env, span)?;
|
let (ty, val) = c.eval(tcx, param_env, span)?;
|
||||||
Ok(tcx.valtree_to_const_val((self.ty(), val)))
|
Ok(tcx.valtree_to_const_val((ty, val)))
|
||||||
}
|
}
|
||||||
Const::Unevaluated(uneval, _) => {
|
Const::Unevaluated(uneval, _) => {
|
||||||
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
|
// FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
|
||||||
|
@ -341,17 +339,16 @@ impl<'tcx> Const<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Option<Scalar> {
|
) -> Option<Scalar> {
|
||||||
match self {
|
if let Const::Ty(c) = self
|
||||||
// THISPR
|
&& let ty::ConstKind::Value(ty, val) = c.kind()
|
||||||
// c.ty().is_primitive()
|
&& ty.is_primitive()
|
||||||
Const::Ty(c) if todo!() => {
|
{
|
||||||
// Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
|
// Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
|
||||||
// are valtree leaves, and *not* on references. (References should return the
|
// are valtree leaves, and *not* on references. (References should return the
|
||||||
// pointer here, which valtrees don't represent.)
|
// pointer here, which valtrees don't represent.)
|
||||||
let val = c.eval(tcx, param_env, DUMMY_SP).ok()?;
|
Some(val.unwrap_leaf().into())
|
||||||
Some(val.unwrap_leaf().into())
|
} else {
|
||||||
}
|
self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
|
||||||
_ => self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,11 +443,10 @@ impl<'tcx> Const<'tcx> {
|
||||||
|
|
||||||
pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||||
match c.kind() {
|
match c.kind() {
|
||||||
ty::ConstKind::Value(valtree) => {
|
ty::ConstKind::Value(ty, valtree) => {
|
||||||
// Make sure that if `c` is normalized, then the return value is normalized.
|
// Make sure that if `c` is normalized, then the return value is normalized.
|
||||||
// THISPR
|
let const_val = tcx.valtree_to_const_val((ty, valtree));
|
||||||
let const_val = tcx.valtree_to_const_val((todo!(), valtree));
|
Self::Val(const_val, ty)
|
||||||
Self::Val(const_val, todo!())
|
|
||||||
}
|
}
|
||||||
_ => Self::Ty(c),
|
_ => Self::Ty(c),
|
||||||
}
|
}
|
||||||
|
@ -469,9 +465,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
// A valtree may be a reference. Valtree references correspond to a
|
// A valtree may be a reference. Valtree references correspond to a
|
||||||
// different allocation each time they are evaluated. Valtrees for primitive
|
// different allocation each time they are evaluated. Valtrees for primitive
|
||||||
// types are fine though.
|
// types are fine though.
|
||||||
// THISPR
|
ty::ConstKind::Value(ty, _) => ty.is_primitive(),
|
||||||
// c.ty().is_primitive()
|
|
||||||
ty::ConstKind::Value(_) => todo!(),
|
|
||||||
ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false,
|
ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false,
|
||||||
// This can happen if evaluation of a constant failed. The result does not matter
|
// This can happen if evaluation of a constant failed. The result does not matter
|
||||||
// much since compilation is doomed.
|
// much since compilation is doomed.
|
||||||
|
|
|
@ -1318,7 +1318,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
|
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(val) => format!("ty::Valtree({})", fmt_valtree(&val)),
|
ty::ConstKind::Value(_, val) => format!("ty::Valtree({})", fmt_valtree(&val)),
|
||||||
// No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
|
// No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
|
||||||
ty::ConstKind::Error(_) => "Error".to_string(),
|
ty::ConstKind::Error(_) => "Error".to_string(),
|
||||||
// These variants shouldn't exist in the MIR.
|
// These variants shouldn't exist in the MIR.
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
|
||||||
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
|
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
rustc_data_structures::static_assert_size!(ConstKind<'_>, 24);
|
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
|
||||||
#[rustc_pass_by_value]
|
#[rustc_pass_by_value]
|
||||||
|
@ -168,10 +168,6 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||||
fn new_unevaluated(interner: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Self {
|
fn new_unevaluated(interner: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Self {
|
||||||
Const::new_unevaluated(interner, uv)
|
Const::new_unevaluated(interner, uv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty(self) -> Ty<'tcx> {
|
|
||||||
self.ty()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Const<'tcx> {
|
impl<'tcx> Const<'tcx> {
|
||||||
|
@ -311,7 +307,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<ValTree<'tcx>, ErrorHandled> {
|
) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> {
|
||||||
assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
|
assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
ConstKind::Unevaluated(unevaluated) => {
|
ConstKind::Unevaluated(unevaluated) => {
|
||||||
|
@ -329,9 +325,9 @@ impl<'tcx> Const<'tcx> {
|
||||||
);
|
);
|
||||||
return Err(e.into());
|
return Err(e.into());
|
||||||
};
|
};
|
||||||
Ok(c)
|
Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c))
|
||||||
}
|
}
|
||||||
ConstKind::Value(val) => Ok(val),
|
ConstKind::Value(ty, val) => Ok((ty, val)),
|
||||||
ConstKind::Error(g) => Err(g.into()),
|
ConstKind::Error(g) => Err(g.into()),
|
||||||
ConstKind::Param(_)
|
ConstKind::Param(_)
|
||||||
| ConstKind::Infer(_)
|
| ConstKind::Infer(_)
|
||||||
|
@ -345,7 +341,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
|
pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
|
||||||
match self.eval(tcx, param_env, DUMMY_SP) {
|
match self.eval(tcx, param_env, DUMMY_SP) {
|
||||||
Ok(val) => Self::new_value(tcx, val, self.ty_for_ctfe(tcx).unwrap()),
|
Ok((ty, val)) => Self::new_value(tcx, val, ty),
|
||||||
Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into()),
|
Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into()),
|
||||||
Err(ErrorHandled::TooGeneric(_span)) => self,
|
Err(ErrorHandled::TooGeneric(_span)) => self,
|
||||||
}
|
}
|
||||||
|
@ -356,8 +352,10 @@ impl<'tcx> Const<'tcx> {
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Option<Scalar> {
|
) -> Option<(Ty<'tcx>, Scalar)> {
|
||||||
self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
|
let (ty, val) = self.eval(tcx, param_env, DUMMY_SP).ok()?;
|
||||||
|
let val = val.try_to_scalar()?;
|
||||||
|
Some((ty, val))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -368,8 +366,10 @@ impl<'tcx> Const<'tcx> {
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
) -> Option<ScalarInt> {
|
) -> Option<(Ty<'tcx>, ScalarInt)> {
|
||||||
self.try_eval_scalar(tcx, param_env)?.try_to_int().ok()
|
let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?;
|
||||||
|
let val = scalar.try_to_int().ok()?;
|
||||||
|
Some((ty, val))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -377,15 +377,10 @@ impl<'tcx> Const<'tcx> {
|
||||||
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
|
||||||
/// contains const generic parameters or pointers).
|
/// contains const generic parameters or pointers).
|
||||||
pub fn try_eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
|
pub fn try_eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
|
||||||
let int = self.try_eval_scalar_int(tcx, param_env)?;
|
let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
|
||||||
let size = tcx
|
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
|
||||||
.layout_of(
|
|
||||||
param_env.with_reveal_all_normalized(tcx).and(self.ty_for_ctfe(tcx).unwrap()),
|
|
||||||
)
|
|
||||||
.ok()?
|
|
||||||
.size;
|
|
||||||
// if `ty` does not depend on generic parameters, use an empty param_env
|
// if `ty` does not depend on generic parameters, use an empty param_env
|
||||||
int.try_to_bits(size).ok()
|
scalar.try_to_bits(size).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -401,12 +396,14 @@ impl<'tcx> Const<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
) -> Option<u64> {
|
) -> Option<u64> {
|
||||||
self.try_eval_scalar_int(tcx, param_env)?.try_to_target_usize(tcx).ok()
|
let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
|
||||||
|
scalar.try_to_target_usize(tcx).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
|
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
|
||||||
self.try_eval_scalar_int(tcx, param_env)?.try_into().ok()
|
let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
|
||||||
|
scalar.try_into().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -419,7 +416,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
/// Panics if self.kind != ty::ConstKind::Value
|
/// Panics if self.kind != ty::ConstKind::Value
|
||||||
pub fn to_valtree(self) -> ty::ValTree<'tcx> {
|
pub fn to_valtree(self) -> ty::ValTree<'tcx> {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
ty::ConstKind::Value(valtree) => valtree,
|
ty::ConstKind::Value(_, valtree) => valtree,
|
||||||
_ => bug!("expected ConstKind::Value, got {:?}", self.kind()),
|
_ => bug!("expected ConstKind::Value, got {:?}", self.kind()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,7 +424,7 @@ impl<'tcx> Const<'tcx> {
|
||||||
/// Attempts to convert to a `ValTree`
|
/// Attempts to convert to a `ValTree`
|
||||||
pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
|
pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
ty::ConstKind::Value(valtree) => Some(valtree),
|
ty::ConstKind::Value(_, valtree) => Some(valtree),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -601,9 +601,15 @@ impl<'tcx> CommonConsts<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
CommonConsts {
|
CommonConsts {
|
||||||
unit: mk_const(ty::ConstKind::Value(ty::ValTree::zst())),
|
unit: mk_const(ty::ConstKind::Value(types.unit, ty::ValTree::zst())),
|
||||||
true_: mk_const(ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::TRUE))),
|
true_: mk_const(ty::ConstKind::Value(
|
||||||
false_: mk_const(ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::FALSE))),
|
types.bool,
|
||||||
|
ty::ValTree::Leaf(ty::ScalarInt::TRUE),
|
||||||
|
)),
|
||||||
|
false_: mk_const(ty::ConstKind::Value(
|
||||||
|
types.bool,
|
||||||
|
ty::ValTree::Leaf(ty::ScalarInt::FALSE),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -337,7 +337,7 @@ impl DeepRejectCtxt {
|
||||||
| ty::ConstKind::Error(_) => {
|
| ty::ConstKind::Error(_) => {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(impl_val) => impl_val,
|
ty::ConstKind::Value(_, impl_val) => impl_val,
|
||||||
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
||||||
bug!("unexpected impl arg: {:?}", impl_ct)
|
bug!("unexpected impl arg: {:?}", impl_ct)
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ impl DeepRejectCtxt {
|
||||||
ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
|
ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(obl_val) => obl_val == impl_val,
|
ty::ConstKind::Value(_, obl_val) => obl_val == impl_val,
|
||||||
|
|
||||||
ty::ConstKind::Infer(_) => true,
|
ty::ConstKind::Infer(_) => true,
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,7 @@ impl FlagComputation {
|
||||||
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
|
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
|
||||||
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
|
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(_) => {}
|
ty::ConstKind::Value(ty, _) => self.add_ty(ty),
|
||||||
ty::ConstKind::Expr(e) => self.add_args(e.args()),
|
ty::ConstKind::Expr(e) => self.add_args(e.args()),
|
||||||
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
|
ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1511,8 +1511,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
_ => print_underscore!(),
|
_ => print_underscore!(),
|
||||||
},
|
},
|
||||||
ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
|
ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
|
||||||
ty::ConstKind::Value(value) => {
|
ty::ConstKind::Value(ty, value) => {
|
||||||
return self.pretty_print_const_valtree(value, todo!(), print_ty);
|
return self.pretty_print_const_valtree(value, ty, print_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ConstKind::Bound(debruijn, bound_var) => {
|
ty::ConstKind::Bound(debruijn, bound_var) => {
|
||||||
|
@ -1666,7 +1666,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
ty::Ref(_, inner, _) => {
|
ty::Ref(_, inner, _) => {
|
||||||
if let ty::Array(elem, len) = inner.kind() {
|
if let ty::Array(elem, len) = inner.kind() {
|
||||||
if let ty::Uint(ty::UintTy::U8) = elem.kind() {
|
if let ty::Uint(ty::UintTy::U8) = elem.kind() {
|
||||||
if let ty::ConstKind::Value(ty::ValTree::Leaf(int)) = len.kind() {
|
if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() {
|
||||||
match self.tcx().try_get_global_alloc(prov.alloc_id()) {
|
match self.tcx().try_get_global_alloc(prov.alloc_id()) {
|
||||||
Some(GlobalAlloc::Memory(alloc)) => {
|
Some(GlobalAlloc::Memory(alloc)) => {
|
||||||
let len = int.assert_bits(self.tcx().data_layout.pointer_size);
|
let len = int.assert_bits(self.tcx().data_layout.pointer_size);
|
||||||
|
|
|
@ -646,7 +646,7 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
|
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
|
||||||
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val,
|
(ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val,
|
||||||
|
|
||||||
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
|
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
|
||||||
// and is the better alternative to waiting until `generic_const_exprs` can
|
// and is the better alternative to waiting until `generic_const_exprs` can
|
||||||
|
|
|
@ -201,18 +201,16 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
f: &mut core::fmt::Formatter<'_>,
|
||||||
) -> core::fmt::Result {
|
) -> core::fmt::Result {
|
||||||
// If this is a value, we spend some effort to make it look nice.
|
// If this is a value, we spend some effort to make it look nice.
|
||||||
if let ConstKind::Value(_) = this.data.kind() {
|
if let ConstKind::Value(_, _) = this.data.kind() {
|
||||||
return ty::tls::with(move |tcx| {
|
return ty::tls::with(move |tcx| {
|
||||||
// Somehow trying to lift the valtree results in lifetime errors, so we lift the
|
// Somehow trying to lift the valtree results in lifetime errors, so we lift the
|
||||||
// entire constant.
|
// entire constant.
|
||||||
let lifted = tcx.lift(*this.data).unwrap();
|
let lifted = tcx.lift(*this.data).unwrap();
|
||||||
let ConstKind::Value(valtree) = lifted.kind() else {
|
let ConstKind::Value(ty, valtree) = lifted.kind() else {
|
||||||
bug!("we checked that this is a valtree")
|
bug!("we checked that this is a valtree")
|
||||||
};
|
};
|
||||||
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
|
let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
|
||||||
// THISPR
|
cx.pretty_print_const_valtree(valtree, ty, /*print_ty*/ true)?;
|
||||||
todo!();
|
|
||||||
// cx.pretty_print_const_valtree(valtree, lifted.ty(), /*print_ty*/ true)?;
|
|
||||||
f.write_str(&cx.into_buffer())
|
f.write_str(&cx.into_buffer())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -652,7 +650,9 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
||||||
}
|
}
|
||||||
ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
|
ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
|
||||||
ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
|
ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
|
||||||
ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
|
ConstKind::Value(t, v) => {
|
||||||
|
ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?)
|
||||||
|
}
|
||||||
ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
|
ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
|
||||||
ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
|
ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
|
||||||
};
|
};
|
||||||
|
@ -671,7 +671,10 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
|
||||||
}
|
}
|
||||||
ConstKind::Placeholder(p) => p.visit_with(visitor),
|
ConstKind::Placeholder(p) => p.visit_with(visitor),
|
||||||
ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
|
ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
|
||||||
ConstKind::Value(v) => v.visit_with(visitor),
|
ConstKind::Value(t, v) => {
|
||||||
|
try_visit!(t.visit_with(visitor));
|
||||||
|
v.visit_with(visitor)
|
||||||
|
}
|
||||||
ConstKind::Error(e) => e.visit_with(visitor),
|
ConstKind::Error(e) => e.visit_with(visitor),
|
||||||
ConstKind::Expr(e) => e.visit_with(visitor),
|
ConstKind::Expr(e) => e.visit_with(visitor),
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,9 +217,10 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||||
| ty::ConstKind::Param(_)
|
| ty::ConstKind::Param(_)
|
||||||
| ty::ConstKind::Placeholder(_)
|
| ty::ConstKind::Placeholder(_)
|
||||||
| ty::ConstKind::Bound(..)
|
| ty::ConstKind::Bound(..)
|
||||||
| ty::ConstKind::Value(_)
|
|
||||||
| ty::ConstKind::Error(_) => {}
|
| ty::ConstKind::Error(_) => {}
|
||||||
|
|
||||||
|
ty::ConstKind::Value(ty, _) => stack.push(ty.into()),
|
||||||
|
|
||||||
ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
|
ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
|
||||||
ty::ConstKind::Unevaluated(ct) => {
|
ty::ConstKind::Unevaluated(ct) => {
|
||||||
stack.extend(ct.args.iter().rev());
|
stack.extend(ct.args.iter().rev());
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// level of indirection can be eliminated
|
// level of indirection can be eliminated
|
||||||
|
|
||||||
let have_valtree =
|
let have_valtree =
|
||||||
matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_)));
|
matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
|
||||||
let inlined_const_as_pat = match cv {
|
let inlined_const_as_pat = match cv {
|
||||||
mir::Const::Ty(c) => match c.kind() {
|
mir::Const::Ty(c) => match c.kind() {
|
||||||
ty::ConstKind::Param(_)
|
ty::ConstKind::Param(_)
|
||||||
|
@ -113,8 +113,8 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
| ty::ConstKind::Expr(_) => {
|
| ty::ConstKind::Expr(_) => {
|
||||||
span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind())
|
span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind())
|
||||||
}
|
}
|
||||||
ty::ConstKind::Value(valtree) => {
|
ty::ConstKind::Value(ty, valtree) => {
|
||||||
self.recur(valtree, cv.ty()).unwrap_or_else(|_: FallbackToOpaqueConst| {
|
self.recur(valtree, ty).unwrap_or_else(|_: FallbackToOpaqueConst| {
|
||||||
Box::new(Pat {
|
Box::new(Pat {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
ty: cv.ty(),
|
ty: cv.ty(),
|
||||||
|
|
|
@ -416,7 +416,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
|
||||||
// FIXME: See comment above -- we could fold the region separately or something.
|
// FIXME: See comment above -- we could fold the region separately or something.
|
||||||
ty::ConstKind::Bound(_, _)
|
ty::ConstKind::Bound(_, _)
|
||||||
| ty::ConstKind::Unevaluated(_)
|
| ty::ConstKind::Unevaluated(_)
|
||||||
| ty::ConstKind::Value(_)
|
| ty::ConstKind::Value(_, _)
|
||||||
| ty::ConstKind::Error(_)
|
| ty::ConstKind::Error(_)
|
||||||
| ty::ConstKind::Expr(_) => return c.super_fold_with(self),
|
| ty::ConstKind::Expr(_) => return c.super_fold_with(self),
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,12 +116,10 @@ fn encode_const<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Literal arguments
|
// Literal arguments
|
||||||
ty::ConstKind::Value(..) => {
|
ty::ConstKind::Value(ct_ty, ..) => {
|
||||||
// L<element-type>[n]<element-value>E as literal argument
|
// L<element-type>[n]<element-value>E as literal argument
|
||||||
|
|
||||||
// Element type
|
// Element type
|
||||||
// THISPR
|
|
||||||
let ct_ty: Ty<'tcx> = todo!();
|
|
||||||
s.push_str(&encode_ty(tcx, ct_ty, dict, options));
|
s.push_str(&encode_ty(tcx, ct_ty, dict, options));
|
||||||
|
|
||||||
// The only allowed types of const values are bool, u8, u16, u32,
|
// The only allowed types of const values are bool, u8, u16, u32,
|
||||||
|
|
|
@ -415,7 +415,7 @@ pub fn mir_const_from_ty_const<'tcx>(
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> stable_mir::ty::MirConst {
|
) -> stable_mir::ty::MirConst {
|
||||||
let kind = match ty_const.kind() {
|
let kind = match ty_const.kind() {
|
||||||
ty::Value(val) => {
|
ty::Value(ty, val) => {
|
||||||
let val = match val {
|
let val = match val {
|
||||||
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
||||||
ty::ValTree::Branch(branch) => {
|
ty::ValTree::Branch(branch) => {
|
||||||
|
@ -456,7 +456,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
||||||
|
|
||||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
let kind = match self.kind() {
|
let kind = match self.kind() {
|
||||||
ty::Value(val) => {
|
ty::Value(ty, val) => {
|
||||||
let val = match val {
|
let val = match val {
|
||||||
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
|
||||||
ty::ValTree::Branch(branch) => {
|
ty::ValTree::Branch(branch) => {
|
||||||
|
@ -464,9 +464,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// THISPR
|
let ty = tables.tcx.lift(ty).unwrap();
|
||||||
let ty = todo!();
|
|
||||||
// let ty = tables.tcx.lift(c.ty()).unwrap();
|
|
||||||
let const_val = tables.tcx.valtree_to_const_val((ty, val));
|
let const_val = tables.tcx.valtree_to_const_val((ty, val));
|
||||||
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
if matches!(const_val, mir::ConstValue::ZeroSized) {
|
||||||
stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables))
|
stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables))
|
||||||
|
|
|
@ -269,21 +269,16 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
|
fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
|
||||||
// THISPR
|
|
||||||
let ct_ty: Ty<'tcx> = todo!();
|
|
||||||
|
|
||||||
// only print integers
|
// only print integers
|
||||||
match (ct.kind(), ct_ty.kind()) {
|
match ct.kind() {
|
||||||
(ty::ConstKind::Value(ty::ValTree::Leaf(scalar)), ty::Int(_) | ty::Uint(_)) => {
|
ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) if ty.is_integral() => {
|
||||||
// The `pretty_print_const` formatting depends on -Zverbose-internals
|
// The `pretty_print_const` formatting depends on -Zverbose-internals
|
||||||
// flag, so we cannot reuse it here.
|
// flag, so we cannot reuse it here.
|
||||||
let signed = matches!(ct_ty.kind(), ty::Int(_));
|
let signed = matches!(ty.kind(), ty::Int(_));
|
||||||
write!(
|
write!(
|
||||||
self,
|
self,
|
||||||
"{:#?}",
|
"{:#?}",
|
||||||
// THISPR
|
ty::ConstInt::new(scalar, signed, ty.is_ptr_sized_integral())
|
||||||
// ct.ty().is_ptr_sized_integral()
|
|
||||||
ty::ConstInt::new(scalar, signed, todo!())
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
_ => self.write_str("_")?,
|
_ => self.write_str("_")?,
|
||||||
|
|
|
@ -541,8 +541,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
|
fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
|
||||||
// We only mangle a typed value if the const can be evaluated.
|
// We only mangle a typed value if the const can be evaluated.
|
||||||
let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
|
let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
|
||||||
match ct.kind() {
|
let (ct_ty, valtree) = match ct.kind() {
|
||||||
ty::ConstKind::Value(_) => {}
|
ty::ConstKind::Value(ty, val) => (ty, val),
|
||||||
|
|
||||||
// Placeholders (should be demangled as `_`).
|
// Placeholders (should be demangled as `_`).
|
||||||
// NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
|
// NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
|
||||||
|
@ -559,7 +559,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
self.push("p");
|
self.push("p");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if let Some(&i) = self.consts.get(&ct) {
|
if let Some(&i) = self.consts.get(&ct) {
|
||||||
self.print_backref(i)?;
|
self.print_backref(i)?;
|
||||||
|
@ -567,18 +567,15 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = self.out.len();
|
let start = self.out.len();
|
||||||
// THISPR
|
|
||||||
let ty: Ty<'tcx> = todo!();
|
|
||||||
// let ty = ct.ty();
|
|
||||||
|
|
||||||
match ty.kind() {
|
match ct_ty.kind() {
|
||||||
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
|
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
|
||||||
ty.print(self)?;
|
ct_ty.print(self)?;
|
||||||
|
|
||||||
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all());
|
let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all());
|
||||||
|
|
||||||
// Negative integer values are mangled using `n` as a "sign prefix".
|
// Negative integer values are mangled using `n` as a "sign prefix".
|
||||||
if let ty::Int(ity) = ty.kind() {
|
if let ty::Int(ity) = ct_ty.kind() {
|
||||||
let val =
|
let val =
|
||||||
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
|
Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
|
||||||
if val < 0 {
|
if val < 0 {
|
||||||
|
@ -600,38 +597,32 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
|
|
||||||
match inner_ty.kind() {
|
match inner_ty.kind() {
|
||||||
ty::Str if mutbl.is_not() => {
|
ty::Str if mutbl.is_not() => {
|
||||||
match ct.kind() {
|
let slice =
|
||||||
ty::ConstKind::Value(valtree) => {
|
valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| {
|
||||||
let slice =
|
bug!(
|
||||||
valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
|
"expected to get raw bytes from valtree {:?} for type {:}",
|
||||||
bug!(
|
valtree,
|
||||||
"expected to get raw bytes from valtree {:?} for type {:}",
|
ct_ty
|
||||||
valtree, ty
|
)
|
||||||
)
|
});
|
||||||
});
|
let s =
|
||||||
let s = std::str::from_utf8(slice)
|
std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
|
||||||
.expect("non utf8 str from MIR interpreter");
|
|
||||||
|
|
||||||
self.push("e");
|
self.push("e");
|
||||||
|
|
||||||
// FIXME(eddyb) use a specialized hex-encoding loop.
|
// FIXME(eddyb) use a specialized hex-encoding loop.
|
||||||
for byte in s.bytes() {
|
for byte in s.bytes() {
|
||||||
let _ = write!(self.out, "{byte:02x}");
|
let _ = write!(self.out, "{byte:02x}");
|
||||||
}
|
|
||||||
|
|
||||||
self.push("_");
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
bug!("symbol_names: unsupported `&str` constant: {:?}", ct);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.push("_");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let pointee_ty =
|
let pointee_ty = ct_ty
|
||||||
ty.builtin_deref(true).expect("tried to dereference on non-ptr type");
|
.builtin_deref(true)
|
||||||
// FIXME(const_generics): add an assert that we only do this for valtrees.
|
.expect("tried to dereference on non-ptr type");
|
||||||
let dereferenced_const = self.tcx.mk_ct_from_kind(ct.kind());
|
let dereferenced_const =
|
||||||
|
ty::Const::new_value(self.tcx, valtree, pointee_ty);
|
||||||
dereferenced_const.print(self)?;
|
dereferenced_const.print(self)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,7 +640,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
match *ty.kind() {
|
match *ct_ty.kind() {
|
||||||
ty::Array(..) | ty::Slice(_) => {
|
ty::Array(..) | ty::Slice(_) => {
|
||||||
self.push("A");
|
self.push("A");
|
||||||
print_field_list(self)?;
|
print_field_list(self)?;
|
||||||
|
@ -698,7 +689,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ty, ct);
|
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct_ty, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1040,8 +1040,13 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
) -> Option<ty::Const<'tcx>> {
|
) -> Option<ty::Const<'tcx>> {
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
|
match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
|
||||||
// THISPR
|
Ok(Some(val)) => Some(ty::Const::new_value(
|
||||||
Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, todo!())),
|
self.interner(),
|
||||||
|
val,
|
||||||
|
self.interner()
|
||||||
|
.type_of(unevaluated.def)
|
||||||
|
.instantiate(self.interner(), unevaluated.args),
|
||||||
|
)),
|
||||||
Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
|
Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
|
||||||
Err(ErrorHandled::Reported(e, _)) => {
|
Err(ErrorHandled::Reported(e, _)) => {
|
||||||
Some(ty::Const::new_error(self.interner(), e.into()))
|
Some(ty::Const::new_error(self.interner(), e.into()))
|
||||||
|
|
|
@ -178,7 +178,9 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||||
ty::ConstKind::Infer(_) => {
|
ty::ConstKind::Infer(_) => {
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
}
|
}
|
||||||
ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
|
ty::ConstKind::Placeholder(_)
|
||||||
|
| ty::ConstKind::Value(_, _)
|
||||||
|
| ty::ConstKind::Error(_) => {
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
// We can freely ICE here as:
|
// We can freely ICE here as:
|
||||||
|
|
|
@ -765,8 +765,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
unevaluated,
|
unevaluated,
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
) {
|
) {
|
||||||
// THISPR
|
Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))),
|
||||||
Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, todo!())),
|
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let reported =
|
let reported =
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||||
ty::ConstKind::Param(_)
|
ty::ConstKind::Param(_)
|
||||||
| ty::ConstKind::Bound(_, _)
|
| ty::ConstKind::Bound(_, _)
|
||||||
| ty::ConstKind::Placeholder(_)
|
| ty::ConstKind::Placeholder(_)
|
||||||
| ty::ConstKind::Value(_)
|
| ty::ConstKind::Value(_, _)
|
||||||
| ty::ConstKind::Error(_) => return Ok(()),
|
| ty::ConstKind::Error(_) => return Ok(()),
|
||||||
ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
|
ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,7 +135,7 @@ mod rustc {
|
||||||
use rustc_middle::ty::ScalarInt;
|
use rustc_middle::ty::ScalarInt;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
|
|
||||||
let Ok(cv) = c.eval(tcx, param_env, DUMMY_SP) else {
|
let Ok((ty, cv)) = c.eval(tcx, param_env, DUMMY_SP) else {
|
||||||
return Some(Self {
|
return Some(Self {
|
||||||
alignment: true,
|
alignment: true,
|
||||||
lifetimes: true,
|
lifetimes: true,
|
||||||
|
@ -144,8 +144,7 @@ mod rustc {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let assume_def_id = tcx.get_lang_items(()).get(LangItem::TransmuteOpts)?;
|
let adt_def = ty.ty_adt_def()?;
|
||||||
let adt_def = tcx.adt_def(assume_def_id);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tcx.require_lang_item(LangItem::TransmuteOpts, None),
|
tcx.require_lang_item(LangItem::TransmuteOpts, None),
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn destructure_const<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
const_: ty::Const<'tcx>,
|
const_: ty::Const<'tcx>,
|
||||||
) -> ty::DestructuredConst<'tcx> {
|
) -> ty::DestructuredConst<'tcx> {
|
||||||
let ty::ConstKind::Value(valtree) = const_.kind() else {
|
let ty::ConstKind::Value(ct_ty, valtree) = const_.kind() else {
|
||||||
bug!("cannot destructure constant {:?}", const_)
|
bug!("cannot destructure constant {:?}", const_)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,9 +32,6 @@ fn destructure_const<'tcx>(
|
||||||
_ => bug!("cannot destructure constant {:?}", const_),
|
_ => bug!("cannot destructure constant {:?}", const_),
|
||||||
};
|
};
|
||||||
|
|
||||||
// THISPR
|
|
||||||
let ct_ty: Ty<'tcx> = todo!();
|
|
||||||
|
|
||||||
let (fields, variant) = match ct_ty.kind() {
|
let (fields, variant) = match ct_ty.kind() {
|
||||||
ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
|
ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
|
||||||
// construct the consts for the elements of the array/slice
|
// construct the consts for the elements of the array/slice
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub enum ConstKind<I: Interner> {
|
||||||
Unevaluated(ty::UnevaluatedConst<I>),
|
Unevaluated(ty::UnevaluatedConst<I>),
|
||||||
|
|
||||||
/// Used to hold computed value.
|
/// Used to hold computed value.
|
||||||
Value(I::ValueConst),
|
Value(I::Ty, I::ValueConst),
|
||||||
|
|
||||||
/// A placeholder for a const which could not be computed; this is
|
/// A placeholder for a const which could not be computed; this is
|
||||||
/// propagated to avoid useless error messages.
|
/// propagated to avoid useless error messages.
|
||||||
|
@ -51,7 +51,7 @@ impl<I: Interner> PartialEq for ConstKind<I> {
|
||||||
(Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1,
|
(Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1,
|
||||||
(Placeholder(l0), Placeholder(r0)) => l0 == r0,
|
(Placeholder(l0), Placeholder(r0)) => l0 == r0,
|
||||||
(Unevaluated(l0), Unevaluated(r0)) => l0 == r0,
|
(Unevaluated(l0), Unevaluated(r0)) => l0 == r0,
|
||||||
(Value(l0), Value(r0)) => l0 == r0,
|
(Value(l0, l1), Value(r0, r1)) => l0 == r0 && l1 == r1,
|
||||||
(Error(l0), Error(r0)) => l0 == r0,
|
(Error(l0), Error(r0)) => l0 == r0,
|
||||||
(Expr(l0), Expr(r0)) => l0 == r0,
|
(Expr(l0), Expr(r0)) => l0 == r0,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -80,7 +80,7 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
|
||||||
Unevaluated(uv) => {
|
Unevaluated(uv) => {
|
||||||
write!(f, "{:?}", &this.wrap(uv))
|
write!(f, "{:?}", &this.wrap(uv))
|
||||||
}
|
}
|
||||||
Value(valtree) => write!(f, "{valtree:?}"),
|
Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &this.wrap(ty)),
|
||||||
Error(_) => write!(f, "{{const error}}"),
|
Error(_) => write!(f, "{{const error}}"),
|
||||||
Expr(expr) => write!(f, "{:?}", &this.wrap(expr)),
|
Expr(expr) => write!(f, "{:?}", &this.wrap(expr)),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue