Skip to content

Commit

Permalink
Remove def_id field from ParamEnv
Browse files Browse the repository at this point in the history
  • Loading branch information
vandenheuvel committed Sep 9, 2020
1 parent 780ca14 commit 7dad29d
Show file tree
Hide file tree
Showing 35 changed files with 288 additions and 337 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/mod.rs
Expand Up @@ -26,7 +26,8 @@ pub fn explicit_outlives_bounds<'tcx>(
| ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::TypeOutlives(..)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => None,
| ty::PredicateAtom::ConstEquate(..)
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/mod.rs
Expand Up @@ -57,7 +57,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;

// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateObligation<'_>, 40);
static_assert_size!(PredicateObligation<'_>, 32);

pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_infer/src/traits/util.rs
Expand Up @@ -236,6 +236,9 @@ impl Elaborator<'tcx> {
.map(|predicate| predicate_obligation(predicate, None)),
);
}
ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
// Nothing to elaborate
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/builtin.rs
Expand Up @@ -1228,7 +1228,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
ClosureKind(..) |
Subtype(..) |
ConstEvaluatable(..) |
ConstEquate(..) => continue,
ConstEquate(..) |
TypeWellFormedFromEnv(..) => continue,
};
if predicate.is_global() {
cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -1399,7 +1399,7 @@ rustc_queries! {
}

query evaluate_goal(
goal: traits::ChalkCanonicalGoal<'tcx>
goal: traits::CanonicalChalkEnvironmentAndGoal<'tcx>
) -> Result<
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
NoSolution
Expand Down
30 changes: 3 additions & 27 deletions compiler/rustc_middle/src/traits/chalk.rs
Expand Up @@ -6,14 +6,11 @@
//! interned Chalk types.

use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
use rustc_middle::ty::{self, AdtDef, TyCtxt};

use rustc_hir::def_id::DefId;
use rustc_target::spec::abi::Abi;

use smallvec::SmallVec;

use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -376,31 +373,10 @@ impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> {
type Interner = Self;
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub enum ChalkEnvironmentClause<'tcx> {
/// A normal rust `ty::Predicate` in the environment.
Predicate(ty::Predicate<'tcx>),
/// A special clause in the environment that gets lowered to
/// `chalk_ir::FromEnv::Ty`.
TypeFromEnv(Ty<'tcx>),
}

impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ChalkEnvironmentClause<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
folder.tcx().intern_chalk_environment_clause_list(&v)
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.iter().any(|t| t.visit_with(visitor))
}
}
/// We have to elaborate the environment of a chalk goal *before*
/// canonicalization. This type wraps the predicate and the elaborated
/// environment.
/// A chalk environment and goal.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
pub struct ChalkEnvironmentAndGoal<'tcx> {
pub environment: &'tcx ty::List<ChalkEnvironmentClause<'tcx>>,
pub environment: &'tcx ty::List<ty::Predicate<'tcx>>,
pub goal: ty::Predicate<'tcx>,
}

Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/traits/mod.rs
Expand Up @@ -26,14 +26,12 @@ use std::rc::Rc;

pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};

pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;
pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>;

pub use self::ImplSource::*;
pub use self::ObligationCauseCode::*;

pub use self::chalk::{
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner,
};
pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner};

/// Depending on the stage of compilation, we want projection to be
/// more or less conservative.
Expand Down
26 changes: 1 addition & 25 deletions compiler/rustc_middle/src/ty/context.rs
Expand Up @@ -91,8 +91,6 @@ pub struct CtxtInterners<'tcx> {
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,

chalk_environment_clause_list: InternedSet<'tcx, List<traits::ChalkEnvironmentClause<'tcx>>>,
}

impl<'tcx> CtxtInterners<'tcx> {
Expand All @@ -110,7 +108,6 @@ impl<'tcx> CtxtInterners<'tcx> {
projs: Default::default(),
place_elems: Default::default(),
const_: Default::default(),
chalk_environment_clause_list: Default::default(),
}
}

Expand Down Expand Up @@ -2041,7 +2038,7 @@ direct_interners! {
}

macro_rules! slice_interners {
($($field:ident: $method:ident($ty:ty)),+) => (
($($field:ident: $method:ident($ty:ty)),+ $(,)?) => (
$(impl<'tcx> TyCtxt<'tcx> {
pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
self.interners.$field.intern_ref(v, || {
Expand All @@ -2060,8 +2057,6 @@ slice_interners!(
predicates: _intern_predicates(Predicate<'tcx>),
projs: _intern_projs(ProjectionKind),
place_elems: _intern_place_elems(PlaceElem<'tcx>),
chalk_environment_clause_list:
_intern_chalk_environment_clause_list(traits::ChalkEnvironmentClause<'tcx>)
);

impl<'tcx> TyCtxt<'tcx> {
Expand Down Expand Up @@ -2460,13 +2455,6 @@ impl<'tcx> TyCtxt<'tcx> {
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
}

pub fn intern_chalk_environment_clause_list(
self,
ts: &[traits::ChalkEnvironmentClause<'tcx>],
) -> &'tcx List<traits::ChalkEnvironmentClause<'tcx>> {
if ts.is_empty() { List::empty() } else { self._intern_chalk_environment_clause_list(ts) }
}

pub fn mk_fn_sig<I>(
self,
inputs: I,
Expand Down Expand Up @@ -2524,18 +2512,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
}

pub fn mk_chalk_environment_clause_list<
I: InternAs<
[traits::ChalkEnvironmentClause<'tcx>],
&'tcx List<traits::ChalkEnvironmentClause<'tcx>>,
>,
>(
self,
iter: I,
) -> I::Output {
iter.intern_with(|xs| self.intern_chalk_environment_clause_list(xs))
}

/// Walks upwards from `id` to find a node which might change lint levels with attributes.
/// It stops at `bound` and just returns it if reached.
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/flags.rs
Expand Up @@ -249,6 +249,9 @@ impl FlagComputation {
self.add_const(expected);
self.add_const(found);
}
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
self.add_ty(ty);
}
}
}

Expand Down
44 changes: 17 additions & 27 deletions compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -1155,6 +1155,11 @@ pub enum PredicateAtom<'tcx> {

/// Constants must be equal. The first component is the const that is expected.
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),

/// Represents a type found in the environment that we can use for implied bounds.
///
/// Only used for Chalk.
TypeWellFormedFromEnv(Ty<'tcx>),
}

impl<'tcx> PredicateAtom<'tcx> {
Expand Down Expand Up @@ -1450,7 +1455,8 @@ impl<'tcx> Predicate<'tcx> {
| PredicateAtom::ClosureKind(..)
| PredicateAtom::TypeOutlives(..)
| PredicateAtom::ConstEvaluatable(..)
| PredicateAtom::ConstEquate(..) => None,
| PredicateAtom::ConstEquate(..)
| PredicateAtom::TypeWellFormedFromEnv(..) => None,
}
}

Expand All @@ -1465,7 +1471,8 @@ impl<'tcx> Predicate<'tcx> {
| PredicateAtom::ObjectSafe(..)
| PredicateAtom::ClosureKind(..)
| PredicateAtom::ConstEvaluatable(..)
| PredicateAtom::ConstEquate(..) => None,
| PredicateAtom::ConstEquate(..)
| PredicateAtom::TypeWellFormedFromEnv(..) => None,
}
}
}
Expand Down Expand Up @@ -1738,11 +1745,6 @@ pub struct ParamEnv<'tcx> {
///
/// Note: This is packed, use the reveal() method to access it.
packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, traits::Reveal, true>,

/// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
/// register that `def_id` (useful for transitioning to the chalk trait
/// solver).
pub def_id: Option<DefId>,
}

unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal {
Expand All @@ -1767,7 +1769,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
f.debug_struct("ParamEnv")
.field("caller_bounds", &self.caller_bounds())
.field("reveal", &self.reveal())
.field("def_id", &self.def_id)
.finish()
}
}
Expand All @@ -1776,23 +1777,16 @@ 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.def_id.hash_stable(hcx, hasher);
}
}

impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
ParamEnv::new(
self.caller_bounds().fold_with(folder),
self.reveal().fold_with(folder),
self.def_id.fold_with(folder),
)
ParamEnv::new(self.caller_bounds().fold_with(folder), self.reveal().fold_with(folder))
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.caller_bounds().visit_with(visitor)
|| self.reveal().visit_with(visitor)
|| self.def_id.visit_with(visitor)
self.caller_bounds().visit_with(visitor) || self.reveal().visit_with(visitor)
}
}

Expand All @@ -1803,7 +1797,7 @@ impl<'tcx> ParamEnv<'tcx> {
/// type-checking.
#[inline]
pub fn empty() -> Self {
Self::new(List::empty(), Reveal::UserFacing, None)
Self::new(List::empty(), Reveal::UserFacing)
}

#[inline]
Expand All @@ -1825,17 +1819,13 @@ impl<'tcx> ParamEnv<'tcx> {
/// or invoke `param_env.with_reveal_all()`.
#[inline]
pub fn reveal_all() -> Self {
Self::new(List::empty(), Reveal::All, None)
Self::new(List::empty(), Reveal::All)
}

/// Construct a trait environment with the given set of predicates.
#[inline]
pub fn new(
caller_bounds: &'tcx List<Predicate<'tcx>>,
reveal: Reveal,
def_id: Option<DefId>,
) -> Self {
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal), def_id }
pub fn new(caller_bounds: &'tcx List<Predicate<'tcx>>, reveal: Reveal) -> Self {
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal) }
}

pub fn with_user_facing(mut self) -> Self {
Expand All @@ -1857,12 +1847,12 @@ impl<'tcx> ParamEnv<'tcx> {
return self;
}

ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All, self.def_id)
ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All)
}

/// Returns this same environment but with no caller bounds.
pub fn without_caller_bounds(self) -> Self {
Self::new(List::empty(), self.reveal(), self.def_id)
Self::new(List::empty(), self.reveal())
}

/// Creates a suitable environment in which to perform trait
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Expand Up @@ -2096,6 +2096,11 @@ define_print_and_forward_display! {
print(c2),
write("`"))
}
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
p!(write("the type `"),
print(ty),
write("` is found in the environment"))
}
}
}

Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/ty/structural_impls.rs
Expand Up @@ -260,6 +260,9 @@ impl fmt::Debug for ty::PredicateAtom<'tcx> {
write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
}
ty::PredicateAtom::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
write!(f, "TypeWellFormedFromEnv({:?})", ty)
}
}
}
}
Expand Down Expand Up @@ -536,6 +539,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
ty::PredicateAtom::ConstEquate(c1, c2) => {
tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateAtom::ConstEquate(c1, c2))
}
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
tcx.lift(&ty).map(ty::PredicateAtom::TypeWellFormedFromEnv)
}
}
}
}
Expand All @@ -551,7 +557,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(), self.def_id))
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
}
}

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir/src/transform/qualify_min_const_fn.rs
Expand Up @@ -30,7 +30,8 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
| ty::PredicateAtom::WellFormed(_)
| ty::PredicateAtom::Projection(_)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => continue,
| ty::PredicateAtom::ConstEquate(..)
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => continue,
ty::PredicateAtom::ObjectSafe(_) => {
bug!("object safe predicate on function: {:#?}", predicate)
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/opaque_types.rs
Expand Up @@ -1261,7 +1261,8 @@ crate fn required_region_bounds(
| ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::RegionOutlives(..)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => None,
| ty::PredicateAtom::ConstEquate(..)
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
// Search for a bound of the form `erased_self_ty
// : 'a`, but be wary of something like `for<'a>
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Expand Up @@ -373,14 +373,12 @@ impl AutoTraitFinder<'tcx> {
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
)
.map(|o| o.predicate);
new_env =
ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal(), None);
new_env = ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal());
}

let final_user_env = ty::ParamEnv::new(
tcx.mk_predicates(user_computed_preds.into_iter()),
user_env.reveal(),
None,
);
debug!(
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
Expand Down

0 comments on commit 7dad29d

Please sign in to comment.