diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty/consts')
-rw-r--r-- | compiler/rustc_middle/src/ty/consts/int.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_middle/src/ty/consts/kind.rs | 45 |
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), } } |