summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/consts
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/consts')
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs5
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs45
2 files changed, 45 insertions, 5 deletions
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index b16163edf..9d99344d5 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -227,6 +227,11 @@ impl ScalarInt {
}
#[inline]
+ pub fn try_from_target_usize(i: impl Into<u128>, tcx: TyCtxt<'_>) -> Option<Self> {
+ Self::try_from_uint(i, tcx.data_layout.pointer_size)
+ }
+
+ #[inline]
pub fn assert_bits(self, target_size: Size) -> u128 {
self.to_bits(target_size).unwrap_or_else(|size| {
bug!("expected int of size {}, but got size {}", target_size.bytes(), size.bytes())
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index db4a15fbe..749b54ca0 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -2,13 +2,13 @@ use super::Const;
use crate::mir;
use crate::ty::abstract_const::CastKind;
use crate::ty::GenericArgsRef;
-use crate::ty::{self, List, Ty};
+use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
/// An unevaluated (potentially generic) constant used in the type-system.
-#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
+#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UnevaluatedConst<'tcx> {
pub def: DefId,
@@ -22,9 +22,37 @@ impl rustc_errors::IntoDiagnosticArg for UnevaluatedConst<'_> {
}
impl<'tcx> UnevaluatedConst<'tcx> {
+ /// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
+ /// hurts performance.
#[inline]
- pub fn expand(self) -> mir::UnevaluatedConst<'tcx> {
- mir::UnevaluatedConst { def: self.def, args: self.args, promoted: None }
+ pub(crate) fn prepare_for_eval(
+ self,
+ tcx: TyCtxt<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ ) -> (ty::ParamEnv<'tcx>, Self) {
+ // 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 args 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.
+ if (param_env, self).has_non_region_infer() {
+ (
+ tcx.param_env(self.def),
+ ty::UnevaluatedConst {
+ def: self.def,
+ args: ty::GenericArgs::identity_for_item(tcx, self.def),
+ },
+ )
+ } else {
+ (tcx.erase_regions(param_env).with_reveal_all_normalized(tcx), tcx.erase_regions(self))
+ }
}
}
@@ -55,6 +83,11 @@ static_assert_size!(super::ConstKind<'_>, 32);
pub enum InferConst<'tcx> {
/// Infer the value of the const.
Var(ty::ConstVid<'tcx>),
+ /// Infer the value of the effect.
+ ///
+ /// For why this is separate from the `Var` variant above, see the
+ /// documentation on `EffectVid`.
+ EffectVar(ty::EffectVid<'tcx>),
/// A fresh const variable. See `infer::freshen` for more details.
Fresh(u32),
}
@@ -62,7 +95,9 @@ pub enum InferConst<'tcx> {
impl<CTX> HashStable<CTX> for InferConst<'_> {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
match self {
- InferConst::Var(_) => panic!("const variables should not be hashed: {self:?}"),
+ InferConst::Var(_) | InferConst::EffectVar(_) => {
+ panic!("const variables should not be hashed: {self:?}")
+ }
InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
}
}