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

Move self trait predicate to items #51895

Merged
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
1 change: 1 addition & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ define_dep_nodes!( <'tcx>
[] GenericsOfItem(DefId),
[] PredicatesOfItem(DefId),
[] ExplicitPredicatesOfItem(DefId),
[] PredicatesDefinedOnItem(DefId),
[] InferredOutlivesOf(DefId),
[] InferredOutlivesCrate(CrateNum),
[] SuperPredicatesOfItem(DefId),
Expand Down
13 changes: 4 additions & 9 deletions src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use hir::def_id::DefId;
use lint;
use traits;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::subst::Substs;
use ty::util::ExplicitSelf;
use std::borrow::Cow;
use syntax::ast;
Expand Down Expand Up @@ -173,10 +172,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
trait_def_id: DefId,
supertraits_only: bool) -> bool
{
let trait_ref = ty::Binder::dummy(ty::TraitRef {
def_id: trait_def_id,
substs: Substs::identity_for_item(self, trait_def_id)
});
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id));
let predicates = if supertraits_only {
self.super_predicates_of(trait_def_id)
} else {
Expand Down Expand Up @@ -391,10 +387,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

// Compute supertraits of current trait lazily.
if supertraits.is_none() {
let trait_ref = ty::Binder::bind(ty::TraitRef {
def_id: trait_def_id,
substs: Substs::identity_for_item(self, trait_def_id)
});
let trait_ref = ty::Binder::bind(
ty::TraitRef::identity(self, trait_def_id),
);
supertraits = Some(traits::supertraits(self, trait_ref).collect());
}

Expand Down
5 changes: 5 additions & 0 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let mut candidates: Vec<EvaluatedCandidate> =
candidates?.into_iter().filter_map(|c| c).collect();

debug!("winnowed to {} candidates for {:?}: {:?}",
candidates.len(),
stack,
candidates);

// If there are STILL multiple candidate, we can further
// reduce the list by dropping duplicates -- including
// resolving specializations.
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2862,8 +2862,8 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
// Compute the bounds on Self and the type parameters.

let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
let predicates = bounds.predicates;
let InstantiatedPredicates { predicates } =
tcx.predicates_of(def_id).instantiate_identity(tcx);

// Finally, we have to normalize the bounds in the environment, in
// case they contain any associated type projections. This process
Expand Down
33 changes: 29 additions & 4 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,39 @@ define_queries! { <'tcx>
[] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,

/// Maps from the def-id of an item (trait/struct/enum/fn) to its
/// associated generics and predicates.
/// associated generics.
[] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,

/// Maps from the def-id of an item (trait/struct/enum/fn) to the
/// predicates (where clauses) that must be proven true in order
/// to reference it. This is almost always the "predicates query"
/// that you want.
///
/// `predicates_of` builds on `predicates_defined_on` -- in fact,
/// it is almost always the same as that query, except for the
/// case of traits. For traits, `predicates_of` contains
/// an additional `Self: Trait<...>` predicate that users don't
/// actually write. This reflects the fact that to invoke the
/// trait (e.g., via `Default::default`) you must supply types
/// that actually implement the trait. (However, this extra
/// predicate gets in the way of some checks, which are intended
/// to operate over only the actual where-clauses written by the
/// user.)
[] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,

/// Maps from the def-id of an item (trait/struct/enum/fn) to the
/// predicates (where clauses) directly defined on it. This is
/// equal to the `explicit_predicates_of` predicates plus the
/// `inferred_outlives_of` predicates.
[] fn predicates_defined_on: PredicatesDefinedOnItem(DefId) -> ty::GenericPredicates<'tcx>,

/// Returns the predicates written explicit by the user.
[] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,

/// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,

/// Maps from the def-id of a trait to the list of
/// super-predicates. This is a subset of the full list of
/// predicates. We store these in a separate map because we must
Expand Down Expand Up @@ -141,9 +169,6 @@ define_queries! { <'tcx>
/// (inferred) variance.
[] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,

/// Maps from def-id of a type to its (inferred) outlives.
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,

/// Maps from def-id of a type to its (inferred) outlives.
[] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
-> Lrc<ty::CratePredicatesMap<'tcx>>,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::TypeOfItem => { force!(type_of, def_id!()); }
DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); }
DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,15 @@ impl<'tcx> TraitRef<'tcx> {
TraitRef { def_id: def_id, substs: substs }
}

/// Returns a TraitRef of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> TraitRef<'tcx> {
TraitRef {
def_id,
substs: Substs::identity_for_item(tcx, def_id),
}
}

pub fn self_ty(&self) -> Ty<'tcx> {
self.substs.type_at(0)
}
Expand Down
15 changes: 15 additions & 0 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
result
}

/// True if `def_id` refers to a closure (e.g., `|x| x * 2`). Note
/// that closures have a def-id, but the closure *expression* also
/// has a `HirId` that is located within the context where the
/// closure appears (and, sadly, a corresponding `NodeId`, since
/// those are not yet phased out). The parent of the closure's
/// def-id will also be the context where it appears.
pub fn is_closure(self, def_id: DefId) -> bool {
self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
}

/// True if `def_id` refers to a trait (e.g., `trait Foo { ... }`).
pub fn is_trait(self, def_id: DefId) -> bool {
if let DefPathData::Trait(_) = self.def_key(def_id).disambiguated_data.data {
true
} else {
false
}
}

/// True if this def-id refers to the implicit constructor for
/// a tuple struct like `struct Foo(u32)`.
pub fn is_struct_constructor(self, def_id: DefId) -> bool {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
}
predicates_of => { cdata.get_predicates(def_id.index, tcx) }
predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
trait_def => {
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,13 @@ impl<'a, 'tcx> CrateMetadata {
self.entry(item_id).predicates.unwrap().decode((self, tcx))
}

pub fn get_predicates_defined_on(&self,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::GenericPredicates<'tcx> {
self.entry(item_id).predicates_defined_on.unwrap().decode((self, tcx))
}

pub fn get_super_predicates(&self,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
Expand Down
27 changes: 27 additions & 0 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: self.encode_optimized_mir(def_id),
}
Expand Down Expand Up @@ -664,6 +665,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,

mir: None
}
Expand Down Expand Up @@ -704,6 +706,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: None,
}
Expand Down Expand Up @@ -761,6 +764,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: self.encode_optimized_mir(def_id),
}
Expand All @@ -778,6 +782,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
self.lazy(&tcx.predicates_of(def_id))
}

fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
debug!("IsolatedEncoder::encode_predicates_defined_on({:?})", def_id);
let tcx = self.tcx;
self.lazy(&tcx.predicates_defined_on(def_id))
}

fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_trait_item({:?})", def_id);
let tcx = self.tcx;
Expand Down Expand Up @@ -867,6 +877,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: self.encode_optimized_mir(def_id),
}
Expand Down Expand Up @@ -963,6 +974,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: if mir { self.encode_optimized_mir(def_id) } else { None },
}
Expand Down Expand Up @@ -1226,6 +1238,16 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
_ => None,
},

// The only time that `predicates_defined_on` is used (on
// an external item) is for traits, during chalk lowering,
// so only encode it in that case as an efficiency
// hack. (No reason not to expand it in the future if
// necessary.)
predicates_defined_on: match item.node {
hir::ItemTrait(..) => Some(self.encode_predicates_defined_on(def_id)),
_ => None, // not *wrong* for other kinds of items, but not needed
},

mir: match item.node {
hir::ItemStatic(..) => {
self.encode_optimized_mir(def_id)
Expand Down Expand Up @@ -1276,6 +1298,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,
mir: None,
}
}
Expand Down Expand Up @@ -1303,6 +1326,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,

mir: None,
}
Expand Down Expand Up @@ -1347,6 +1371,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: None,
predicates_defined_on: None,

mir: self.encode_optimized_mir(def_id),
}
Expand Down Expand Up @@ -1374,6 +1399,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
variances: LazySeq::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: self.encode_optimized_mir(def_id),
}
Expand Down Expand Up @@ -1575,6 +1601,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,

mir: None,
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_metadata/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub struct Entry<'tcx> {
pub variances: LazySeq<ty::Variance>,
pub generics: Option<Lazy<ty::Generics>>,
pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,

pub mir: Option<Lazy<mir::Mir<'tcx>>>,
}
Expand All @@ -290,6 +291,7 @@ impl_stable_hash_for!(struct Entry<'tcx> {
variances,
generics,
predicates,
predicates_defined_on,
mir
});

Expand Down
12 changes: 3 additions & 9 deletions src/librustc_traits/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use rustc::hir::{self, ImplPolarity};
use rustc::traits::{Clause, Clauses, DomainGoal, Goal, PolyDomainGoal, ProgramClause,
WhereClause, FromEnv, WellFormed};
use rustc::ty::query::Providers;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Slice, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use std::mem;
Expand Down Expand Up @@ -225,10 +224,7 @@ fn program_clauses_for_trait<'a, 'tcx>(

// `Self: Trait<P1..Pn>`
let trait_pred = ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id,
substs: Substs::identity_for_item(tcx, def_id),
},
trait_ref: ty::TraitRef::identity(tcx, def_id),
};

// `Implemented(Self: Trait<P1..Pn>)`
Expand Down Expand Up @@ -256,10 +252,8 @@ fn program_clauses_for_trait<'a, 'tcx>(
// ```

// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
// FIXME: Remove the [1..] slice; this is a hack because the query
// predicates_of currently includes the trait itself (`Self: Trait<P1..Pn>`).
let where_clauses = &tcx.predicates_of(def_id).predicates;
let implied_bound_clauses = where_clauses[1..]
let where_clauses = &tcx.predicates_defined_on(def_id).predicates;
let implied_bound_clauses = where_clauses
.into_iter()
.map(|wc| wc.lower())

Expand Down
Loading