Add constness to ParamEnv

This now causes a lot of queries to be executed twice, as reveal_all forces NotConst
This commit is contained in:
Oli Scherer
2021-10-21 14:56:00 +00:00
committed by Deadbeef
parent 22eeff700e
commit 721ffd14c3
8 changed files with 126 additions and 45 deletions

View File

@@ -1227,22 +1227,27 @@ pub struct ParamEnv<'tcx> {
#[derive(Copy, Clone)]
struct ParamTag {
reveal: traits::Reveal,
constness: hir::Constness,
}
unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
const BITS: usize = 1;
const BITS: usize = 2;
#[inline]
fn into_usize(self) -> usize {
match self {
Self { reveal: traits::Reveal::UserFacing } => 0,
Self { reveal: traits::Reveal::All } => 1,
Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0,
Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1,
Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2,
Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3,
}
}
#[inline]
unsafe fn from_usize(ptr: usize) -> Self {
match ptr {
0 => Self { reveal: traits::Reveal::UserFacing },
1 => Self { reveal: traits::Reveal::All },
0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst },
1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst },
2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const },
3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const },
_ => std::hint::unreachable_unchecked(),
}
}
@@ -1253,6 +1258,7 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
f.debug_struct("ParamEnv")
.field("caller_bounds", &self.caller_bounds())
.field("reveal", &self.reveal())
.field("constness", &self.constness())
.finish()
}
}
@@ -1261,20 +1267,23 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
self.caller_bounds().hash_stable(hcx, hasher);
self.reveal().hash_stable(hcx, hasher);
self.constness().hash_stable(hcx, hasher);
}
}
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(ParamEnv::new(self.caller_bounds().fold_with(folder)?, self.reveal().fold_with(folder)?))
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
ParamEnv::new(
self.caller_bounds().fold_with(folder)?,
self.reveal().fold_with(folder)?,
self.constness().fold_with(folder)?,
)
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.caller_bounds().visit_with(visitor)?;
self.reveal().visit_with(visitor)
self.reveal().visit_with(visitor)?;
self.constness().visit_with(visitor)
}
}
@@ -1285,7 +1294,7 @@ impl<'tcx> ParamEnv<'tcx> {
/// type-checking.
#[inline]
pub fn empty() -> Self {
Self::new(List::empty(), Reveal::UserFacing)
Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst)
}
#[inline]
@@ -1298,6 +1307,11 @@ impl<'tcx> ParamEnv<'tcx> {
self.packed.tag().reveal
}
#[inline]
pub fn constness(self) -> hir::Constness {
self.packed.tag().constness
}
/// Construct a trait environment with no where-clauses in scope
/// where the values of all `impl Trait` and other hidden types
/// are revealed. This is suitable for monomorphized, post-typeck
@@ -1307,13 +1321,17 @@ impl<'tcx> ParamEnv<'tcx> {
/// or invoke `param_env.with_reveal_all()`.
#[inline]
pub fn reveal_all() -> Self {
Self::new(List::empty(), Reveal::All)
Self::new(List::empty(), Reveal::All, hir::Constness::NotConst)
}
/// Construct a trait environment with the given set of predicates.
#[inline]
pub fn new(caller_bounds: &'tcx List<Predicate<'tcx>>, reveal: Reveal) -> Self {
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
pub fn new(
caller_bounds: &'tcx List<Predicate<'tcx>>,
reveal: Reveal,
constness: hir::Constness,
) -> Self {
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) }
}
pub fn with_user_facing(mut self) -> Self {
@@ -1335,13 +1353,17 @@ impl<'tcx> ParamEnv<'tcx> {
return self;
}
ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All)
ParamEnv::new(
tcx.normalize_opaque_types(self.caller_bounds()),
Reveal::All,
self.constness(),
)
}
/// Returns this same environment but with no caller bounds.
#[inline]
pub fn without_caller_bounds(self) -> Self {
Self::new(List::empty(), self.reveal())
Self::new(List::empty(), self.reveal(), self.constness())
}
/// Creates a suitable environment in which to perform trait