Auto merge of #91549 - fee1-dead:const_env, r=spastorino

Eliminate ConstnessAnd again

Closes #91489.
Closes #89432.

Reverts #91491.
Reverts #89450.

r? `@spastorino`
This commit is contained in:
bors 2021-12-12 22:15:32 +00:00
commit 22f8bde876
69 changed files with 622 additions and 458 deletions

View file

@ -474,7 +474,8 @@ impl<'hir> Map<'hir> {
/// Panics if `LocalDefId` does not have an associated body.
///
/// This should only be used for determining the context of a body, a return
/// value of `Some` does not always suggest that the owner of the body is `const`.
/// value of `Some` does not always suggest that the owner of the body is `const`,
/// just that it has to be checked as if it were.
pub fn body_const_context(&self, did: LocalDefId) -> Option<ConstContext> {
let hir_id = self.local_def_id_to_hir_id(did);
let ccx = match self.body_owner_kind(hir_id) {

View file

@ -246,6 +246,14 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
}
}
impl<'tcx, R> Canonical<'tcx, ty::ParamEnvAnd<'tcx, R>> {
#[inline]
pub fn without_const(mut self) -> Self {
self.value = self.value.without_const();
self
}
}
impl<'tcx, V> Canonical<'tcx, V> {
/// Allows you to map the `value` of a canonical while keeping the
/// same set of bound variables.

View file

@ -64,6 +64,7 @@ impl<'tcx> TyCtxt<'tcx> {
cid: GlobalId<'tcx>,
span: Option<Span>,
) -> EvalToConstValueResult<'tcx> {
let param_env = param_env.with_const();
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
// improve caching of queries.
let inputs = self.erase_regions(param_env.and(cid));
@ -92,6 +93,7 @@ impl<'tcx> TyCtxt<'tcx> {
gid: GlobalId<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Result<&'tcx mir::Allocation, ErrorHandled> {
let param_env = param_env.with_const();
trace!("eval_to_allocation: Need to compute {:?}", gid);
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())

View file

@ -880,6 +880,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, ConstAlloc<'tcx>>
) -> Option<ty::ValTree<'tcx>> {
desc { "destructure constant" }
remap_env_constness
}
/// Destructure a constant ADT or array into its variant index and its
@ -888,6 +889,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> {
desc { "destructure constant" }
remap_env_constness
}
/// Dereference a constant reference or raw pointer and turn the result into a constant
@ -896,6 +898,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
) -> &'tcx ty::Const<'tcx> {
desc { "deref constant" }
remap_env_constness
}
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
@ -1100,26 +1103,32 @@ rustc_queries! {
/// `ty.is_copy()`, etc, since that will prune the environment where possible.
query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Copy`", env.value }
remap_env_constness
}
/// Query backing `TyS::is_sized`.
query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Sized`", env.value }
remap_env_constness
}
/// Query backing `TyS::is_freeze`.
query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is freeze", env.value }
remap_env_constness
}
/// Query backing `TyS::is_unpin`.
query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Unpin`", env.value }
remap_env_constness
}
/// Query backing `TyS::needs_drop`.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` needs drop", env.value }
remap_env_constness
}
/// Query backing `TyS::has_significant_drop_raw`.
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` has a significant drop", env.value }
remap_env_constness
}
/// Query backing `TyS::is_structural_eq_shallow`.
@ -1158,6 +1167,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> {
desc { "computing layout of `{}`", key.value }
remap_env_constness
}
/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
@ -1168,6 +1178,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
desc { "computing call ABI of `{}` function pointers", key.value.0 }
remap_env_constness
}
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for
@ -1179,6 +1190,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> {
desc { "computing call ABI of `{}`", key.value.0 }
remap_env_constness
}
query dylib_dependency_formats(_: CrateNum)
@ -1463,6 +1475,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> ty::inhabitedness::DefIdForest {
desc { "computing the inhabitedness of `{:?}`", key }
remap_env_constness
}
query dep_kind(_: CrateNum) -> CrateDepKind {
@ -1642,6 +1655,7 @@ rustc_queries! {
NoSolution,
> {
desc { "normalizing `{:?}`", goal }
remap_env_constness
}
// FIXME: Implement `normalize_generic_arg_after_erasing_regions` and
@ -1654,6 +1668,7 @@ rustc_queries! {
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
) -> GenericArg<'tcx> {
desc { "normalizing `{}`", goal.value }
remap_env_constness
}
/// Do not call this query directly: invoke `normalize_erasing_regions` instead.
@ -1661,6 +1676,7 @@ rustc_queries! {
goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
) -> mir::ConstantKind<'tcx> {
desc { "normalizing `{}`", goal.value }
remap_env_constness
}
/// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
@ -1668,6 +1684,7 @@ rustc_queries! {
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
) -> Result<GenericArg<'tcx>, NoSolution> {
desc { "normalizing `{}`", goal.value }
remap_env_constness
}
/// Do not call this query directly: invoke `try_normalize_erasing_regions` instead.
@ -1675,6 +1692,7 @@ rustc_queries! {
goal: ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
) -> Result<mir::ConstantKind<'tcx>, NoSolution> {
desc { "normalizing `{}`", goal.value }
remap_env_constness
}
query implied_outlives_bounds(
@ -1684,6 +1702,7 @@ rustc_queries! {
NoSolution,
> {
desc { "computing implied outlives bounds for `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
@ -1694,6 +1713,7 @@ rustc_queries! {
NoSolution,
> {
desc { "computing dropck types for `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: invoke `infcx.predicate_may_hold()` or
@ -1721,6 +1741,7 @@ rustc_queries! {
NoSolution,
> {
desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `Eq` type-op
@ -1731,6 +1752,7 @@ rustc_queries! {
NoSolution,
> {
desc { "evaluating `type_op_eq` `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `Subtype` type-op
@ -1741,6 +1763,7 @@ rustc_queries! {
NoSolution,
> {
desc { "evaluating `type_op_subtype` `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `ProvePredicate` type-op
@ -1761,6 +1784,7 @@ rustc_queries! {
NoSolution,
> {
desc { "normalizing `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `Normalize` type-op
@ -1771,6 +1795,7 @@ rustc_queries! {
NoSolution,
> {
desc { "normalizing `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `Normalize` type-op
@ -1781,6 +1806,7 @@ rustc_queries! {
NoSolution,
> {
desc { "normalizing `{:?}`", goal }
remap_env_constness
}
/// Do not call this query directly: part of the `Normalize` type-op
@ -1791,6 +1817,7 @@ rustc_queries! {
NoSolution,
> {
desc { "normalizing `{:?}`", goal }
remap_env_constness
}
query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
@ -1804,6 +1831,7 @@ rustc_queries! {
goal: CanonicalTyGoal<'tcx>
) -> MethodAutoderefStepsResult<'tcx> {
desc { "computing autoderef types for `{:?}`", goal }
remap_env_constness
}
query supported_target_features(_: CrateNum) -> FxHashMap<String, Option<Symbol>> {
@ -1836,6 +1864,7 @@ rustc_queries! {
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>
) -> Result<Option<ty::Instance<'tcx>>, ErrorReported> {
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
remap_env_constness
}
query resolve_instance_of_const_arg(
@ -1845,6 +1874,7 @@ rustc_queries! {
"resolving instance of the const argument `{}`",
ty::Instance::new(key.value.0.to_def_id(), key.value.2),
}
remap_env_constness
}
query normalize_opaque_types(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> {
@ -1859,6 +1889,7 @@ rustc_queries! {
/// size, to account for partial initialisation. See #49298 for details.)
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "conservatively checking if {:?} is privately uninhabited", key }
remap_env_constness
}
query limits(key: ()) -> Limits {

View file

@ -12,14 +12,12 @@ use rustc_hir::def_id::DefId;
use rustc_query_system::cache::Cache;
pub type SelectionCache<'tcx> = Cache<
(ty::ConstnessAnd<ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>>, ty::ImplPolarity),
ty::ParamEnvAnd<'tcx, ty::TraitPredicate<'tcx>>,
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
>;
pub type EvaluationCache<'tcx> = Cache<
(ty::ParamEnvAnd<'tcx, ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>>, ty::ImplPolarity),
EvaluationResult,
>;
pub type EvaluationCache<'tcx> =
Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitPredicate<'tcx>>, EvaluationResult>;
/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes
@ -103,7 +101,7 @@ pub enum SelectionCandidate<'tcx> {
/// `false` if there are no *further* obligations.
has_nested: bool,
},
ParamCandidate((ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>, ty::ImplPolarity)),
ParamCandidate(ty::PolyTraitPredicate<'tcx>),
ImplCandidate(DefId),
AutoImplCandidate(DefId),

View file

@ -26,9 +26,9 @@ impl<'tcx> Elaborator<'tcx> {
.predicates
.into_iter()
.flat_map(|(pred, _)| {
pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_ref()
pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_pred()
})
.map(|t| t.value)
.map(|t| t.map_bound(|pred| pred.trait_ref))
.filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
self.stack.extend(supertrait_refs);

View file

@ -230,6 +230,19 @@ pub enum BoundConstness {
ConstIfConst,
}
impl BoundConstness {
/// Reduce `self` and `constness` to two possible combined states instead of four.
pub fn and(&mut self, constness: hir::Constness) -> hir::Constness {
match (constness, self) {
(hir::Constness::Const, BoundConstness::ConstIfConst) => hir::Constness::Const,
(_, this) => {
*this = BoundConstness::NotConst;
hir::Constness::NotConst
}
}
}
}
impl fmt::Display for BoundConstness {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -846,20 +859,6 @@ impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
}
}
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
.map_bound(|trait_ref| {
PredicateKind::Trait(ty::TraitPredicate {
trait_ref,
constness: self.constness,
polarity: ty::ImplPolarity::Positive,
})
})
.to_predicate(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateKind::Trait).to_predicate(tcx)
@ -885,12 +884,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
}
impl<'tcx> Predicate<'tcx> {
pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
pub fn to_opt_poly_trait_pred(self) -> Option<PolyTraitPredicate<'tcx>> {
let predicate = self.kind();
match predicate.skip_binder() {
PredicateKind::Trait(t) => {
Some(ConstnessAnd { constness: t.constness, value: predicate.rebind(t.trait_ref) })
}
PredicateKind::Trait(t) => Some(predicate.rebind(t)),
PredicateKind::Projection(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
@ -1221,23 +1218,33 @@ pub struct ParamEnv<'tcx> {
/// want `Reveal::All`.
///
/// Note: This is packed, use the reveal() method to access it.
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, traits::Reveal, true>,
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, ParamTag, true>,
}
unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal {
const BITS: usize = 1;
#[derive(Copy, Clone)]
struct ParamTag {
reveal: traits::Reveal,
constness: hir::Constness,
}
unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
const BITS: usize = 2;
#[inline]
fn into_usize(self) -> usize {
match self {
traits::Reveal::UserFacing => 0,
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 => traits::Reveal::UserFacing,
1 => 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(),
}
}
@ -1248,6 +1255,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()
}
}
@ -1256,6 +1264,7 @@ 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);
}
}
@ -1267,12 +1276,14 @@ impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
Ok(ParamEnv::new(
self.caller_bounds().try_fold_with(folder)?,
self.reveal().try_fold_with(folder)?,
self.constness().try_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)
}
}
@ -1283,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]
@ -1293,7 +1304,12 @@ impl<'tcx> ParamEnv<'tcx> {
#[inline]
pub fn reveal(self) -> traits::Reveal {
self.packed.tag()
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
@ -1305,20 +1321,47 @@ 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, 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 {
self.packed.set_tag(Reveal::UserFacing);
self.packed.set_tag(ParamTag { reveal: Reveal::UserFacing, ..self.packed.tag() });
self
}
#[inline]
pub fn with_constness(mut self, constness: hir::Constness) -> Self {
self.packed.set_tag(ParamTag { constness, ..self.packed.tag() });
self
}
#[inline]
pub fn with_const(mut self) -> Self {
self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() });
self
}
#[inline]
pub fn without_const(mut self) -> Self {
self.packed.set_tag(ParamTag { constness: hir::Constness::NotConst, ..self.packed.tag() });
self
}
#[inline]
pub fn remap_constness_with(&mut self, mut constness: ty::BoundConstness) {
*self = self.with_constness(constness.and(self.constness()))
}
/// Returns a new parameter environment with the same clauses, but
/// which "reveals" the true results of projections in all cases
/// (even for associated types that are specializable). This is
@ -1329,17 +1372,21 @@ impl<'tcx> ParamEnv<'tcx> {
/// will be normalized to their underlying types.
/// See PR #65989 and issue #65918 for more details
pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self {
if self.packed.tag() == traits::Reveal::All {
if self.packed.tag().reveal == traits::Reveal::All {
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
@ -1369,33 +1416,23 @@ impl<'tcx> ParamEnv<'tcx> {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
pub struct ConstnessAnd<T> {
pub constness: BoundConstness,
pub value: T,
}
// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate(tcx)` to ensure that
// the constness of trait bounds is being propagated correctly.
pub trait WithConstness: Sized {
impl PolyTraitRef<'tcx> {
#[inline]
fn with_constness(self, constness: BoundConstness) -> ConstnessAnd<Self> {
ConstnessAnd { constness, value: self }
pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tcx> {
self.map_bound(|trait_ref| ty::TraitPredicate {
trait_ref,
constness,
polarity: ty::ImplPolarity::Positive,
})
}
#[inline]
fn with_const_if_const(self) -> ConstnessAnd<Self> {
self.with_constness(BoundConstness::ConstIfConst)
}
#[inline]
fn without_const(self) -> ConstnessAnd<Self> {
pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
self.with_constness(BoundConstness::NotConst)
}
}
impl<T> WithConstness for T {}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
pub struct ParamEnvAnd<'tcx, T> {
pub param_env: ParamEnv<'tcx>,
@ -1406,6 +1443,12 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> {
pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
(self.param_env, self.value)
}
#[inline]
pub fn without_const(mut self) -> Self {
self.param_env = self.param_env.without_const();
self
}
}
impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T>

View file

@ -156,6 +156,16 @@ macro_rules! separate_provide_extern_default {
};
}
macro_rules! opt_remap_env_constness {
([][$name:ident]) => {};
([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
let $name = $name.without_const();
};
([$other:tt $($modifiers:tt)*][$name:ident]) => {
opt_remap_env_constness!([$($modifiers)*][$name])
};
}
macro_rules! define_callbacks {
(<$tcx:tt>
$($(#[$attr:meta])*
@ -202,6 +212,8 @@ macro_rules! define_callbacks {
#[inline(always)]
pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
let key = key.into_query_param();
opt_remap_env_constness!([$($modifiers)*][key]);
let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
let lookup = match cached {
@ -229,6 +241,8 @@ macro_rules! define_callbacks {
pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
{
let key = key.into_query_param();
opt_remap_env_constness!([$($modifiers)*][key]);
let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, Clone::clone);
let lookup = match cached {

View file

@ -218,19 +218,6 @@ impl<'tcx> Relate<'tcx> for ty::BoundConstness {
}
}
impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::ConstnessAnd<T> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::ConstnessAnd<T>,
b: ty::ConstnessAnd<T>,
) -> RelateResult<'tcx, ty::ConstnessAnd<T>> {
Ok(ty::ConstnessAnd {
constness: relation.relate(a.constness, b.constness)?,
value: relation.relate(a.value, b.value)?,
})
}
}
impl<'tcx> Relate<'tcx> for ast::Unsafety {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,

View file

@ -480,7 +480,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
type Lifted = ty::ParamEnv<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(self.caller_bounds())
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
}
}

View file

@ -8,9 +8,7 @@ use crate::infer::canonical::Canonical;
use crate::ty::fold::ValidateBoundVars;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::InferTy::{self, *};
use crate::ty::{
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
};
use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv, TyS};
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;