Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing the def_id field from hot ParamEnv to make it smaller #76244

Merged
merged 1 commit into from
Sep 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
vandenheuvel marked this conversation as resolved.
Show resolved Hide resolved
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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]>>();
vandenheuvel marked this conversation as resolved.
Show resolved Hide resolved
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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:
vandenheuvel marked this conversation as resolved.
Show resolved Hide resolved
_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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading