summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/consts
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_middle/src/ty/consts
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/ty/consts')
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs9
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs204
2 files changed, 12 insertions, 201 deletions
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index d1dbc531e..1e43fab45 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -1,5 +1,6 @@
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_target::abi::Size;
use std::fmt;
@@ -113,6 +114,14 @@ impl std::fmt::Debug for ConstInt {
}
}
+impl IntoDiagnosticArg for ConstInt {
+ // FIXME this simply uses the Debug impl, but we could probably do better by converting both
+ // to an inherent method that returns `Cow`.
+ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(format!("{self:?}").into())
+ }
+}
+
/// The raw bytes of a simple value.
///
/// This is a packed struct in order to allow this type to be optimally embedded in enums
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 1dd4f8a24..a6bf74911 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -1,17 +1,11 @@
use super::Const;
use crate::mir;
-use crate::mir::interpret::{AllocId, ConstValue, Scalar};
use crate::ty::abstract_const::CastKind;
-use crate::ty::subst::{InternalSubsts, SubstsRef};
-use crate::ty::ParamEnv;
-use crate::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
+use crate::ty::subst::SubstsRef;
+use crate::ty::{self, List, Ty};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
-use rustc_target::abi::Size;
-
-use super::ScalarInt;
/// An unevaluated (potentially generic) constant used in the type-system.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
@@ -41,45 +35,6 @@ impl<'tcx> UnevaluatedConst<'tcx> {
}
}
-/// Represents a constant in Rust.
-#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
-#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
-#[derive(derive_more::From)]
-pub enum ConstKind<'tcx> {
- /// A const generic parameter.
- Param(ty::ParamConst),
-
- /// Infer the value of the const.
- Infer(InferConst<'tcx>),
-
- /// Bound const variable, used only when preparing a trait query.
- Bound(ty::DebruijnIndex, ty::BoundVar),
-
- /// A placeholder const - universally quantified higher-ranked const.
- Placeholder(ty::PlaceholderConst<'tcx>),
-
- /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
- /// variants when the code is monomorphic enough for that.
- Unevaluated(UnevaluatedConst<'tcx>),
-
- /// Used to hold computed value.
- Value(ty::ValTree<'tcx>),
-
- /// A placeholder for a const which could not be computed; this is
- /// propagated to avoid useless error messages.
- #[from(ignore)]
- Error(ErrorGuaranteed),
-
- /// Expr which contains an expression which has partially evaluated items.
- Expr(Expr<'tcx>),
-}
-
-impl<'tcx> From<ty::ConstVid<'tcx>> for ConstKind<'tcx> {
- fn from(const_vid: ty::ConstVid<'tcx>) -> Self {
- InferConst::Var(const_vid).into()
- }
-}
-
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
pub enum Expr<'tcx> {
@@ -93,39 +48,7 @@ pub enum Expr<'tcx> {
static_assert_size!(Expr<'_>, 24);
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(ConstKind<'_>, 32);
-
-impl<'tcx> ConstKind<'tcx> {
- #[inline]
- pub fn try_to_value(self) -> Option<ty::ValTree<'tcx>> {
- if let ConstKind::Value(val) = self { Some(val) } else { None }
- }
-
- #[inline]
- pub fn try_to_scalar(self) -> Option<Scalar<AllocId>> {
- self.try_to_value()?.try_to_scalar()
- }
-
- #[inline]
- pub fn try_to_scalar_int(self) -> Option<ScalarInt> {
- self.try_to_value()?.try_to_scalar_int()
- }
-
- #[inline]
- pub fn try_to_bits(self, size: Size) -> Option<u128> {
- self.try_to_scalar_int()?.to_bits(size).ok()
- }
-
- #[inline]
- pub fn try_to_bool(self) -> Option<bool> {
- self.try_to_scalar_int()?.try_into().ok()
- }
-
- #[inline]
- pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
- self.try_to_value()?.try_to_target_usize(tcx)
- }
-}
+static_assert_size!(super::ConstKind<'_>, 32);
/// An inference variable for a const, for use in const generics.
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
@@ -144,124 +67,3 @@ impl<CTX> HashStable<CTX> for InferConst<'_> {
}
}
}
-
-enum EvalMode {
- Typeck,
- Mir,
-}
-
-enum EvalResult<'tcx> {
- ValTree(ty::ValTree<'tcx>),
- ConstVal(ConstValue<'tcx>),
-}
-
-impl<'tcx> ConstKind<'tcx> {
- #[inline]
- /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
- /// unevaluated constant.
- pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
- self.try_eval_for_typeck(tcx, param_env).and_then(Result::ok).map_or(self, ConstKind::Value)
- }
-
- #[inline]
- /// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary
- /// return `None`.
- // FIXME(@lcnr): Completely rework the evaluation/normalization system for `ty::Const` once valtrees are merged.
- pub fn try_eval_for_mir(
- self,
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- ) -> Option<Result<ConstValue<'tcx>, ErrorGuaranteed>> {
- match self.try_eval_inner(tcx, param_env, EvalMode::Mir) {
- Some(Ok(EvalResult::ValTree(_))) => unreachable!(),
- Some(Ok(EvalResult::ConstVal(v))) => Some(Ok(v)),
- Some(Err(e)) => Some(Err(e)),
- None => None,
- }
- }
-
- #[inline]
- /// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary
- /// return `None`.
- // FIXME(@lcnr): Completely rework the evaluation/normalization system for `ty::Const` once valtrees are merged.
- pub fn try_eval_for_typeck(
- self,
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- ) -> Option<Result<ty::ValTree<'tcx>, ErrorGuaranteed>> {
- match self.try_eval_inner(tcx, param_env, EvalMode::Typeck) {
- Some(Ok(EvalResult::ValTree(v))) => Some(Ok(v)),
- Some(Ok(EvalResult::ConstVal(_))) => unreachable!(),
- Some(Err(e)) => Some(Err(e)),
- None => None,
- }
- }
-
- #[inline]
- fn try_eval_inner(
- self,
- tcx: TyCtxt<'tcx>,
- param_env: ParamEnv<'tcx>,
- eval_mode: EvalMode,
- ) -> Option<Result<EvalResult<'tcx>, ErrorGuaranteed>> {
- assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
- if let ConstKind::Unevaluated(unevaluated) = self {
- use crate::mir::interpret::ErrorHandled;
-
- // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
- // also does later, but we want to do it before checking for
- // inference variables.
- // Note that we erase regions *before* calling `with_reveal_all_normalized`,
- // so that we don't try to invoke this query with
- // any region variables.
-
- // HACK(eddyb) when the query key would contain inference variables,
- // attempt using identity substs and `ParamEnv` instead, that will succeed
- // when the expression doesn't depend on any parameters.
- // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
- // we can call `infcx.const_eval_resolve` which handles inference variables.
- let param_env_and = if (param_env, unevaluated).has_non_region_infer() {
- tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst {
- def: unevaluated.def,
- substs: InternalSubsts::identity_for_item(tcx, unevaluated.def),
- })
- } else {
- tcx.erase_regions(param_env)
- .with_reveal_all_normalized(tcx)
- .and(tcx.erase_regions(unevaluated))
- };
-
- // FIXME(eddyb) maybe the `const_eval_*` methods should take
- // `ty::ParamEnvAnd` instead of having them separate.
- let (param_env, unevaluated) = param_env_and.into_parts();
- // try to resolve e.g. associated constants to their definition on an impl, and then
- // evaluate the const.
- match eval_mode {
- EvalMode::Typeck => {
- match tcx.const_eval_resolve_for_typeck(param_env, unevaluated, None) {
- // NOTE(eddyb) `val` contains no lifetimes/types/consts,
- // and we use the original type, so nothing from `substs`
- // (which may be identity substs, see above),
- // can leak through `val` into the const we return.
- Ok(val) => Some(Ok(EvalResult::ValTree(val?))),
- Err(ErrorHandled::TooGeneric) => None,
- Err(ErrorHandled::Reported(e)) => Some(Err(e.into())),
- }
- }
- EvalMode::Mir => {
- match tcx.const_eval_resolve(param_env, unevaluated.expand(), None) {
- // NOTE(eddyb) `val` contains no lifetimes/types/consts,
- // and we use the original type, so nothing from `substs`
- // (which may be identity substs, see above),
- // can leak through `val` into the const we return.
- Ok(val) => Some(Ok(EvalResult::ConstVal(val))),
- Err(ErrorHandled::TooGeneric) => None,
- Err(ErrorHandled::Reported(e)) => Some(Err(e.into())),
- }
- }
- }
- } else {
- None
- }
- }
-}