1
Fork 0

rustc: arena-allocate the slice in ty::GenericsPredicate, not the whole struct.

This commit is contained in:
Eduard-Mihai Burtescu 2019-10-18 03:14:57 +03:00
parent b04338087e
commit cd9e4441eb
27 changed files with 120 additions and 138 deletions

View file

@ -98,7 +98,6 @@ macro_rules! arena_types {
rustc::hir::def_id::DefId, rustc::hir::def_id::DefId,
>, >,
[few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes, [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
[decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
[few] lint_levels: rustc::lint::LintLevelMap, [few] lint_levels: rustc::lint::LintLevelMap,
[few] stability_index: rustc::middle::stability::Index<'tcx>, [few] stability_index: rustc::middle::stability::Index<'tcx>,
[few] features: syntax::feature_gate::Features, [few] features: syntax::feature_gate::Features,

View file

@ -61,7 +61,7 @@ rustc_queries! {
/// predicate gets in the way of some checks, which are intended /// predicate gets in the way of some checks, which are intended
/// to operate over only the actual where-clauses written by the /// to operate over only the actual where-clauses written by the
/// user.) /// user.)
query predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> { query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
} }
@ -184,12 +184,10 @@ rustc_queries! {
/// predicates (where-clauses) directly defined on it. This is /// predicates (where-clauses) directly defined on it. This is
/// equal to the `explicit_predicates_of` predicates plus the /// equal to the `explicit_predicates_of` predicates plus the
/// `inferred_outlives_of` predicates. /// `inferred_outlives_of` predicates.
query predicates_defined_on(_: DefId) query predicates_defined_on(_: DefId) -> ty::GenericPredicates<'tcx> {}
-> &'tcx ty::GenericPredicates<'tcx> {}
/// Returns the predicates written explicitly by the user. /// Returns the predicates written explicitly by the user.
query explicit_predicates_of(_: DefId) query explicit_predicates_of(_: DefId) -> ty::GenericPredicates<'tcx> {}
-> &'tcx ty::GenericPredicates<'tcx> {}
/// Returns the inferred outlives predicates (e.g., for `struct /// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
@ -201,14 +199,13 @@ rustc_queries! {
/// evaluate them even during type conversion, often before the /// evaluate them even during type conversion, often before the
/// full predicates are available (note that supertraits have /// full predicates are available (note that supertraits have
/// additional acyclicity requirements). /// additional acyclicity requirements).
query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> { query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) } desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
} }
/// To avoid cycles within the predicates of a single item we compute /// To avoid cycles within the predicates of a single item we compute
/// per-type-parameter predicates for resolving `T::AssocTy`. /// per-type-parameter predicates for resolving `T::AssocTy`.
query type_param_predicates(key: (DefId, DefId)) query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> {
-> &'tcx ty::GenericPredicates<'tcx> {
no_force no_force
desc { |tcx| "computing the bounds for type parameter `{}`", { desc { |tcx| "computing the bounds for type parameter `{}`", {
let id = tcx.hir().as_local_hir_id(key.1).unwrap(); let id = tcx.hir().as_local_hir_id(key.1).unwrap();

View file

@ -419,7 +419,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
// The predicates will contain default bounds like `T: Sized`. We need to // The predicates will contain default bounds like `T: Sized`. We need to
// remove these bounds, and add `T: ?Sized` to any untouched type parameters. // remove these bounds, and add `T: ?Sized` to any untouched type parameters.
let predicates = &tcx.predicates_of(impl_def_id).predicates; let predicates = tcx.predicates_of(impl_def_id).predicates;
let mut pretty_predicates = Vec::with_capacity( let mut pretty_predicates = Vec::with_capacity(
predicates.len() + types_without_default_bounds.len()); predicates.len() + types_without_default_bounds.len());

View file

@ -16,6 +16,7 @@ use std::intrinsics;
use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{self, Ty, TyCtxt};
use crate::ty::subst::SubstsRef; use crate::ty::subst::SubstsRef;
use crate::mir::interpret::Allocation; use crate::mir::interpret::Allocation;
use syntax_pos::Span;
/// The shorthand encoding uses an enum's variant index `usize` /// The shorthand encoding uses an enum's variant index `usize`
/// and is offset by this value so it never matches a real variant. /// and is offset by this value so it never matches a real variant.
@ -92,16 +93,16 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E,
Ok(()) Ok(())
} }
pub fn encode_predicates<'tcx, E, C>(encoder: &mut E, pub fn encode_spanned_predicates<'tcx, E, C>(
predicates: &ty::GenericPredicates<'tcx>, encoder: &mut E,
cache: C) predicates: &'tcx [(ty::Predicate<'tcx>, Span)],
-> Result<(), E::Error> cache: C,
) -> Result<(), E::Error>
where E: TyEncoder, where E: TyEncoder,
C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>, C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>,
{ {
predicates.parent.encode(encoder)?; predicates.len().encode(encoder)?;
predicates.predicates.len().encode(encoder)?; for (predicate, span) in predicates {
for (predicate, span) in &predicates.predicates {
encode_with_shorthand(encoder, predicate, &cache)?; encode_with_shorthand(encoder, predicate, &cache)?;
span.encode(encoder)?; span.encode(encoder)?;
} }
@ -182,13 +183,15 @@ where
} }
#[inline] #[inline]
pub fn decode_predicates<D>(decoder: &mut D) -> Result<ty::GenericPredicates<'tcx>, D::Error> pub fn decode_spanned_predicates<D>(
decoder: &mut D,
) -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], D::Error>
where where
D: TyDecoder<'tcx>, D: TyDecoder<'tcx>,
{ {
Ok(ty::GenericPredicates { let tcx = decoder.tcx();
parent: Decodable::decode(decoder)?, Ok(tcx.arena.alloc_from_iter(
predicates: (0..decoder.read_usize()?).map(|_| { (0..decoder.read_usize()?).map(|_| {
// Handle shorthands first, if we have an usize > 0x80. // Handle shorthands first, if we have an usize > 0x80.
let predicate = if decoder.positioned_at_shorthand() { let predicate = if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize()?; let pos = decoder.read_usize()?;
@ -202,7 +205,7 @@ where
Ok((predicate, Decodable::decode(decoder)?)) Ok((predicate, Decodable::decode(decoder)?))
}) })
.collect::<Result<Vec<_>, _>>()?, .collect::<Result<Vec<_>, _>>()?,
}) ))
} }
#[inline] #[inline]
@ -339,6 +342,8 @@ macro_rules! implement_ty_decoder {
use $crate::ty::subst::SubstsRef; use $crate::ty::subst::SubstsRef;
use $crate::hir::def_id::{CrateNum}; use $crate::hir::def_id::{CrateNum};
use syntax_pos::Span;
use super::$DecoderName; use super::$DecoderName;
impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
@ -393,11 +398,11 @@ macro_rules! implement_ty_decoder {
} }
} }
impl<$($typaram),*> SpecializedDecoder<ty::GenericPredicates<'tcx>> impl<$($typaram),*> SpecializedDecoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) fn specialized_decode(&mut self)
-> Result<ty::GenericPredicates<'tcx>, Self::Error> { -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], Self::Error> {
decode_predicates(self) decode_spanned_predicates(self)
} }
} }

View file

@ -148,10 +148,6 @@ impl<'tcx> CtxtInterners<'tcx> {
} }
} }
pub struct Common<'tcx> {
pub empty_predicates: ty::GenericPredicates<'tcx>,
}
pub struct CommonTypes<'tcx> { pub struct CommonTypes<'tcx> {
pub unit: Ty<'tcx>, pub unit: Ty<'tcx>,
pub bool: Ty<'tcx>, pub bool: Ty<'tcx>,
@ -1039,9 +1035,6 @@ pub struct GlobalCtxt<'tcx> {
pub prof: SelfProfilerRef, pub prof: SelfProfilerRef,
/// Common objects.
pub common: Common<'tcx>,
/// Common types, pre-interned for your convenience. /// Common types, pre-interned for your convenience.
pub types: CommonTypes<'tcx>, pub types: CommonTypes<'tcx>,
@ -1213,12 +1206,6 @@ impl<'tcx> TyCtxt<'tcx> {
s.fatal(&err); s.fatal(&err);
}); });
let interners = CtxtInterners::new(&arenas.interner); let interners = CtxtInterners::new(&arenas.interner);
let common = Common {
empty_predicates: ty::GenericPredicates {
parent: None,
predicates: vec![],
},
};
let common_types = CommonTypes::new(&interners); let common_types = CommonTypes::new(&interners);
let common_lifetimes = CommonLifetimes::new(&interners); let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types); let common_consts = CommonConsts::new(&interners, &common_types);
@ -1273,7 +1260,6 @@ impl<'tcx> TyCtxt<'tcx> {
interners, interners,
dep_graph, dep_graph,
prof: s.prof.clone(), prof: s.prof.clone(),
common,
types: common_types, types: common_types,
lifetimes: common_lifetimes, lifetimes: common_lifetimes,
consts: common_consts, consts: common_consts,

View file

@ -1018,15 +1018,12 @@ impl<'tcx> Generics {
} }
/// Bounds on generics. /// Bounds on generics.
#[derive(Clone, Default, Debug, HashStable)] #[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct GenericPredicates<'tcx> { pub struct GenericPredicates<'tcx> {
pub parent: Option<DefId>, pub parent: Option<DefId>,
pub predicates: Vec<(Predicate<'tcx>, Span)>, pub predicates: &'tcx [(Predicate<'tcx>, Span)],
} }
impl<'tcx> rustc_serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
impl<'tcx> rustc_serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}
impl<'tcx> GenericPredicates<'tcx> { impl<'tcx> GenericPredicates<'tcx> {
pub fn instantiate( pub fn instantiate(
&self, &self,
@ -2321,7 +2318,7 @@ impl<'tcx> AdtDef {
} }
#[inline] #[inline]
pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> &'tcx GenericPredicates<'tcx> { pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
tcx.predicates_of(self.did) tcx.predicates_of(self.did)
} }
@ -2561,7 +2558,7 @@ impl<'tcx> AdtDef {
def_id: sized_trait, def_id: sized_trait,
substs: tcx.mk_substs_trait(ty, &[]) substs: tcx.mk_substs_trait(ty, &[])
}).to_predicate(); }).to_predicate();
let predicates = &tcx.predicates_of(self.did).predicates; let predicates = tcx.predicates_of(self.did).predicates;
if predicates.iter().any(|(p, _)| *p == sized_predicate) { if predicates.iter().any(|(p, _)| *p == sized_predicate) {
vec![] vec![]
} else { } else {

View file

@ -882,15 +882,16 @@ where
} }
} }
impl<'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>> for CacheEncoder<'a, 'tcx, E> impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
for CacheEncoder<'a, 'tcx, E>
where where
E: 'a + TyEncoder, E: 'a + TyEncoder,
{ {
#[inline] #[inline]
fn specialized_encode(&mut self, fn specialized_encode(&mut self,
predicates: &ty::GenericPredicates<'tcx>) predicates: &&'tcx [(ty::Predicate<'tcx>, Span)])
-> Result<(), Self::Error> { -> Result<(), Self::Error> {
ty_codec::encode_predicates(self, predicates, ty_codec::encode_spanned_predicates(self, predicates,
|encoder| &mut encoder.predicate_shorthands) |encoder| &mut encoder.predicate_shorthands)
} }
} }

View file

@ -1218,12 +1218,6 @@ EnumTypeFoldableImpl! {
} }
} }
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
parent, predicates
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
// This code is hot enough that it's worth specializing for a list of // This code is hot enough that it's worth specializing for a list of

View file

@ -1241,7 +1241,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
if cx.tcx.features().trivial_bounds { if cx.tcx.features().trivial_bounds {
let def_id = cx.tcx.hir().local_def_id(item.hir_id); let def_id = cx.tcx.hir().local_def_id(item.hir_id);
let predicates = cx.tcx.predicates_of(def_id); let predicates = cx.tcx.predicates_of(def_id);
for &(predicate, span) in &predicates.predicates { for &(predicate, span) in predicates.predicates {
let predicate_kind_name = match predicate { let predicate_kind_name = match predicate {
Trait(..) => "Trait", Trait(..) => "Trait",
TypeOutlives(..) | TypeOutlives(..) |

View file

@ -156,7 +156,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
} }
ty::Opaque(def, _) => { ty::Opaque(def, _) => {
let mut has_emitted = false; let mut has_emitted = false;
for (predicate, _) in &cx.tcx.predicates_of(def).predicates { for (predicate, _) in cx.tcx.predicates_of(def).predicates {
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
let def_id = trait_ref.def_id; let def_id = trait_ref.def_id;

View file

@ -97,11 +97,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
generics_of => { generics_of => {
tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess)) tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess))
} }
predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) } predicates_of => { cdata.get_predicates(def_id.index, tcx) }
predicates_defined_on => { predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx)) super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
}
super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) }
trait_def => { trait_def => {
tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess)) tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess))
} }

View file

@ -243,11 +243,11 @@ impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
} }
} }
impl<'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'tcx> { impl<'tcx> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for EncodeContext<'tcx> {
fn specialized_encode(&mut self, fn specialized_encode(&mut self,
predicates: &ty::GenericPredicates<'tcx>) predicates: &&'tcx [(ty::Predicate<'tcx>, Span)])
-> Result<(), Self::Error> { -> Result<(), Self::Error> {
ty_codec::encode_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands) ty_codec::encode_spanned_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands)
} }
} }
@ -826,13 +826,13 @@ impl EncodeContext<'tcx> {
fn encode_predicates(&mut self, def_id: DefId) { fn encode_predicates(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates({:?})", def_id); debug!("EncodeContext::encode_predicates({:?})", def_id);
record!(self.per_def.predicates[def_id] <- &*self.tcx.predicates_of(def_id)); record!(self.per_def.predicates[def_id] <- self.tcx.predicates_of(def_id));
} }
fn encode_predicates_defined_on(&mut self, def_id: DefId) { fn encode_predicates_defined_on(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id); debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
record!(self.per_def.predicates_defined_on[def_id] <- record!(self.per_def.predicates_defined_on[def_id] <-
&*self.tcx.predicates_defined_on(def_id)) self.tcx.predicates_defined_on(def_id))
} }
fn encode_info_for_trait_item(&mut self, def_id: DefId) { fn encode_info_for_trait_item(&mut self, def_id: DefId) {
@ -1166,14 +1166,14 @@ impl EncodeContext<'tcx> {
paren_sugar: trait_def.paren_sugar, paren_sugar: trait_def.paren_sugar,
has_auto_impl: self.tcx.trait_is_auto(def_id), has_auto_impl: self.tcx.trait_is_auto(def_id),
is_marker: trait_def.is_marker, is_marker: trait_def.is_marker,
super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)), super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
}; };
EntryKind::Trait(self.lazy(data)) EntryKind::Trait(self.lazy(data))
} }
hir::ItemKind::TraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
let data = TraitAliasData { let data = TraitAliasData {
super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)), super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
}; };
EntryKind::TraitAlias(self.lazy(data)) EntryKind::TraitAlias(self.lazy(data))

View file

@ -14,7 +14,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
let mut current = def_id; let mut current = def_id;
loop { loop {
let predicates = tcx.predicates_of(current); let predicates = tcx.predicates_of(current);
for (predicate, _) in &predicates.predicates { for (predicate, _) in predicates.predicates {
match predicate { match predicate {
| Predicate::RegionOutlives(_) | Predicate::RegionOutlives(_)
| Predicate::TypeOutlives(_) | Predicate::TypeOutlives(_)

View file

@ -64,7 +64,7 @@ trait DefIdVisitor<'tcx> {
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
self.skeleton().visit_trait(trait_ref) self.skeleton().visit_trait(trait_ref)
} }
fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
self.skeleton().visit_predicates(predicates) self.skeleton().visit_predicates(predicates)
} }
} }
@ -88,7 +88,7 @@ where
(!self.def_id_visitor.shallow() && substs.visit_with(self)) (!self.def_id_visitor.shallow() && substs.visit_with(self))
} }
fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
let ty::GenericPredicates { parent: _, predicates } = predicates; let ty::GenericPredicates { parent: _, predicates } = predicates;
for (predicate, _span) in predicates { for (predicate, _span) in predicates {
match predicate { match predicate {

View file

@ -218,7 +218,7 @@ fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env)); let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env));
let predicates = &tcx.predicates_defined_on(def_id).predicates; let predicates = tcx.predicates_defined_on(def_id).predicates;
// Warning: these where clauses are not substituted for bound vars yet, // Warning: these where clauses are not substituted for bound vars yet,
// so that we don't need to adjust binders in the `FromEnv` rules below // so that we don't need to adjust binders in the `FromEnv` rules below
@ -319,7 +319,7 @@ fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
let trait_pred = ty::TraitPredicate { trait_ref }.lower(); let trait_pred = ty::TraitPredicate { trait_ref }.lower();
// `WC` // `WC`
let predicates = &tcx.predicates_of(def_id).predicates; let predicates = tcx.predicates_of(def_id).predicates;
let where_clauses = predicates let where_clauses = predicates
.iter() .iter()
.map(|(wc, _)| wc.lower()) .map(|(wc, _)| wc.lower())

View file

@ -54,8 +54,7 @@ pub trait AstConv<'tcx> {
/// but this can lead to cycle errors. The problem is that we have /// but this can lead to cycle errors. The problem is that we have
/// to do this resolution *in order to create the predicates in /// to do this resolution *in order to create the predicates in
/// the first place*. Hence, we have this "special pass". /// the first place*. Hence, we have this "special pass".
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx>;
-> &'tcx ty::GenericPredicates<'tcx>;
/// Returns the lifetime to use when a lifetime is omitted (and not elided). /// Returns the lifetime to use when a lifetime is omitted (and not elided).
fn re_infer( fn re_infer(

View file

@ -44,7 +44,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
ensure_drop_predicates_are_implied_by_item_defn( ensure_drop_predicates_are_implied_by_item_defn(
tcx, tcx,
drop_impl_did, drop_impl_did,
&dtor_predicates, dtor_predicates,
adt_def.did, adt_def.did,
self_to_impl_substs, self_to_impl_substs,
) )
@ -140,7 +140,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
drop_impl_did: DefId, drop_impl_did: DefId,
dtor_predicates: &ty::GenericPredicates<'tcx>, dtor_predicates: ty::GenericPredicates<'tcx>,
self_type_did: DefId, self_type_did: DefId,
self_to_impl_substs: SubstsRef<'tcx>, self_to_impl_substs: SubstsRef<'tcx>,
) -> Result<(), ErrorReported> { ) -> Result<(), ErrorReported> {
@ -199,7 +199,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// just to look for all the predicates directly. // just to look for all the predicates directly.
assert_eq!(dtor_predicates.parent, None); assert_eq!(dtor_predicates.parent, None);
for (predicate, _) in &dtor_predicates.predicates { for (predicate, _) in dtor_predicates.predicates {
// (We do not need to worry about deep analysis of type // (We do not need to worry about deep analysis of type
// expressions etc because the Drop impls are already forced // expressions etc because the Drop impls are already forced
// to take on a structure that is roughly an alpha-renaming of // to take on a structure that is roughly an alpha-renaming of

View file

@ -2245,19 +2245,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.tcx self.tcx
} }
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
-> &'tcx ty::GenericPredicates<'tcx>
{
let tcx = self.tcx; let tcx = self.tcx;
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
let item_id = tcx.hir().ty_param_owner(hir_id); let item_id = tcx.hir().ty_param_owner(hir_id);
let item_def_id = tcx.hir().local_def_id(item_id); let item_def_id = tcx.hir().local_def_id(item_id);
let generics = tcx.generics_of(item_def_id); let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id]; let index = generics.param_def_id_to_index[&def_id];
tcx.arena.alloc(ty::GenericPredicates { ty::GenericPredicates {
parent: None, parent: None,
predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { predicates: tcx.arena.alloc_from_iter(
match predicate { self.param_env.caller_bounds.iter().filter_map(|&predicate| match predicate {
ty::Predicate::Trait(ref data) ty::Predicate::Trait(ref data)
if data.skip_binder().self_ty().is_param(index) => { if data.skip_binder().self_ty().is_param(index) => {
// HACK(eddyb) should get the original `Span`. // HACK(eddyb) should get the original `Span`.
@ -2265,9 +2263,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
Some((predicate, span)) Some((predicate, span))
} }
_ => None _ => None
} }),
}).collect() ),
}) }
} }
fn re_infer( fn re_infer(

View file

@ -791,7 +791,7 @@ fn check_opaque_types<'fcx, 'tcx>(
"check_opaque_types: may define, predicates={:#?}", "check_opaque_types: may define, predicates={:#?}",
predicates, predicates,
); );
for &(pred, _) in predicates.predicates.iter() { for &(pred, _) in predicates.predicates {
let substituted_pred = pred.subst(fcx.tcx, substs); let substituted_pred = pred.subst(fcx.tcx, substs);
// Avoid duplication of predicates that contain no parameters, for example. // Avoid duplication of predicates that contain no parameters, for example.
if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
@ -1011,7 +1011,7 @@ fn check_variances_for_type_defn<'tcx>(
identify_constrained_generic_params( identify_constrained_generic_params(
tcx, tcx,
&ty_predicates, ty_predicates,
None, None,
&mut constrained_parameters, &mut constrained_parameters,
); );

View file

@ -182,8 +182,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
self.tcx self.tcx
} }
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
-> &'tcx ty::GenericPredicates<'tcx> {
self.tcx self.tcx
.at(span) .at(span)
.type_param_predicates((self.item_def_id, def_id)) .type_param_predicates((self.item_def_id, def_id))
@ -254,7 +253,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
fn type_param_predicates( fn type_param_predicates(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
(item_def_id, def_id): (DefId, DefId), (item_def_id, def_id): (DefId, DefId),
) -> &ty::GenericPredicates<'_> { ) -> ty::GenericPredicates<'_> {
use rustc::hir::*; use rustc::hir::*;
// In the AST, bounds can derive from two places. Either // In the AST, bounds can derive from two places. Either
@ -275,10 +274,10 @@ fn type_param_predicates(
tcx.generics_of(item_def_id).parent tcx.generics_of(item_def_id).parent
}; };
let result = parent.map_or(&tcx.common.empty_predicates, |parent| { let mut result = parent.map(|parent| {
let icx = ItemCtxt::new(tcx, parent); let icx = ItemCtxt::new(tcx, parent);
icx.get_type_parameter_bounds(DUMMY_SP, def_id) icx.get_type_parameter_bounds(DUMMY_SP, def_id)
}); }).unwrap_or_default();
let mut extend = None; let mut extend = None;
let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap(); let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap();
@ -321,9 +320,7 @@ fn type_param_predicates(
}; };
let icx = ItemCtxt::new(tcx, item_def_id); let icx = ItemCtxt::new(tcx, item_def_id);
let mut result = (*result).clone(); let extra_predicates = extend.into_iter().chain(
result.predicates.extend(extend.into_iter());
result.predicates.extend(
icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true)) icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
.into_iter() .into_iter()
.filter(|(predicate, _)| { .filter(|(predicate, _)| {
@ -331,9 +328,12 @@ fn type_param_predicates(
ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index), ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index),
_ => false, _ => false,
} }
}) }),
); );
tcx.arena.alloc(result) result.predicates = tcx.arena.alloc_from_iter(
result.predicates.iter().copied().chain(extra_predicates),
);
result
} }
impl ItemCtxt<'tcx> { impl ItemCtxt<'tcx> {
@ -698,7 +698,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
fn super_predicates_of( fn super_predicates_of(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
trait_def_id: DefId, trait_def_id: DefId,
) -> &ty::GenericPredicates<'_> { ) -> ty::GenericPredicates<'_> {
debug!("super_predicates(trait_def_id={:?})", trait_def_id); debug!("super_predicates(trait_def_id={:?})", trait_def_id);
let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap(); let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap();
@ -732,21 +732,23 @@ fn super_predicates_of(
generics, item.hir_id, self_param_ty, OnlySelfBounds(!is_trait_alias)); generics, item.hir_id, self_param_ty, OnlySelfBounds(!is_trait_alias));
// Combine the two lists to form the complete set of superbounds: // Combine the two lists to form the complete set of superbounds:
let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect(); let superbounds = &*tcx.arena.alloc_from_iter(
superbounds1.into_iter().chain(superbounds2)
);
// Now require that immediate supertraits are converted, // Now require that immediate supertraits are converted,
// which will, in turn, reach indirect supertraits. // which will, in turn, reach indirect supertraits.
for &(pred, span) in &superbounds { for &(pred, span) in superbounds {
debug!("superbound: {:?}", pred); debug!("superbound: {:?}", pred);
if let ty::Predicate::Trait(bound) = pred { if let ty::Predicate::Trait(bound) = pred {
tcx.at(span).super_predicates_of(bound.def_id()); tcx.at(span).super_predicates_of(bound.def_id());
} }
} }
tcx.arena.alloc(ty::GenericPredicates { ty::GenericPredicates {
parent: None, parent: None,
predicates: superbounds, predicates: superbounds,
}) }
} }
fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef { fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef {
@ -1958,7 +1960,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
fn predicates_defined_on( fn predicates_defined_on(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> &ty::GenericPredicates<'_> { ) -> ty::GenericPredicates<'_> {
debug!("predicates_defined_on({:?})", def_id); debug!("predicates_defined_on({:?})", def_id);
let mut result = tcx.explicit_predicates_of(def_id); let mut result = tcx.explicit_predicates_of(def_id);
debug!( debug!(
@ -1974,9 +1976,13 @@ fn predicates_defined_on(
def_id, def_id,
inferred_outlives, inferred_outlives,
); );
let mut predicates = (*result).clone(); result.predicates = tcx.arena.alloc_from_iter(
predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span))); result.predicates.iter().copied().chain(
result = tcx.arena.alloc(predicates); // FIXME(eddyb) use better spans - maybe add `Span`s
// to `inferred_outlives_of` predicates as well?
inferred_outlives.iter().map(|&p| (p, span)),
),
);
} }
debug!("predicates_defined_on({:?}) = {:?}", def_id, result); debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
result result
@ -1985,7 +1991,7 @@ fn predicates_defined_on(
/// Returns a list of all type predicates (explicit and implicit) for the definition with /// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
/// `Self: Trait` predicates for traits. /// `Self: Trait` predicates for traits.
fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> { fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
let mut result = tcx.predicates_defined_on(def_id); let mut result = tcx.predicates_defined_on(def_id);
if tcx.is_trait(def_id) { if tcx.is_trait(def_id) {
@ -2002,9 +2008,11 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
// used, and adding the predicate into this list ensures // used, and adding the predicate into this list ensures
// that this is done. // that this is done.
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let mut predicates = (*result).clone(); result.predicates = tcx.arena.alloc_from_iter(
predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); result.predicates.iter().copied().chain(
result = tcx.arena.alloc(predicates); std::iter::once((ty::TraitRef::identity(tcx, def_id).to_predicate(), span))
),
);
} }
debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
result result
@ -2015,7 +2023,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
fn explicit_predicates_of( fn explicit_predicates_of(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> &ty::GenericPredicates<'_> { ) -> ty::GenericPredicates<'_> {
use rustc::hir::*; use rustc::hir::*;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -2024,6 +2032,7 @@ fn explicit_predicates_of(
/// A data structure with unique elements, which preserves order of insertion. /// A data structure with unique elements, which preserves order of insertion.
/// Preserving the order of insertion is important here so as not to break /// Preserving the order of insertion is important here so as not to break
/// compile-fail UI tests. /// compile-fail UI tests.
// FIXME(eddyb) just use `IndexSet` from `indexmap`.
struct UniquePredicates<'tcx> { struct UniquePredicates<'tcx> {
predicates: Vec<(ty::Predicate<'tcx>, Span)>, predicates: Vec<(ty::Predicate<'tcx>, Span)>,
uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>, uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>,
@ -2133,10 +2142,10 @@ fn explicit_predicates_of(
let bounds_predicates = bounds.predicates(tcx, opaque_ty); let bounds_predicates = bounds.predicates(tcx, opaque_ty);
if impl_trait_fn.is_some() { if impl_trait_fn.is_some() {
// opaque types // opaque types
return tcx.arena.alloc(ty::GenericPredicates { return ty::GenericPredicates {
parent: None, parent: None,
predicates: bounds_predicates, predicates: tcx.arena.alloc_from_iter(bounds_predicates),
}); };
} else { } else {
// named opaque types // named opaque types
predicates.extend(bounds_predicates); predicates.extend(bounds_predicates);
@ -2339,10 +2348,10 @@ fn explicit_predicates_of(
); );
} }
let result = tcx.arena.alloc(ty::GenericPredicates { let result = ty::GenericPredicates {
parent: generics.parent, parent: generics.parent,
predicates, predicates: tcx.arena.alloc_from_iter(predicates),
}); };
debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result); debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
result result
} }

View file

@ -86,11 +86,11 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
pub fn identify_constrained_generic_params<'tcx>( pub fn identify_constrained_generic_params<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
predicates: &ty::GenericPredicates<'tcx>, predicates: ty::GenericPredicates<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>, impl_trait_ref: Option<ty::TraitRef<'tcx>>,
input_parameters: &mut FxHashSet<Parameter>, input_parameters: &mut FxHashSet<Parameter>,
) { ) {
let mut predicates = predicates.predicates.clone(); let mut predicates = predicates.predicates.to_vec();
setup_constraining_predicates(tcx, &mut predicates, impl_trait_ref, input_parameters); setup_constraining_predicates(tcx, &mut predicates, impl_trait_ref, input_parameters);
} }

View file

@ -114,7 +114,7 @@ fn enforce_impl_params_are_constrained(
let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref);
cgp::identify_constrained_generic_params( cgp::identify_constrained_generic_params(
tcx, &impl_predicates, impl_trait_ref, &mut input_parameters); tcx, impl_predicates, impl_trait_ref, &mut input_parameters);
// Disallow unconstrained lifetimes, but only if they appear in assoc types. // Disallow unconstrained lifetimes, but only if they appear in assoc types.
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()

View file

@ -30,7 +30,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
let mut required_predicates = RequiredPredicates::default(); let mut required_predicates = RequiredPredicates::default();
// process predicates and convert to `RequiredPredicates` entry, see below // process predicates and convert to `RequiredPredicates` entry, see below
for (pred, _) in predicates.predicates.iter() { for (pred, _) in predicates.predicates {
match pred { match pred {
ty::Predicate::TypeOutlives(predicate) => { ty::Predicate::TypeOutlives(predicate) => {
let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder(); let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();

View file

@ -104,7 +104,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// regardless of the choice of `T`. // regardless of the choice of `T`.
let params = ( let params = (
self.cx.tcx.generics_of(param_env_def_id), self.cx.tcx.generics_of(param_env_def_id),
&&self.cx.tcx.common.empty_predicates, ty::GenericPredicates::default(),
).clean(self.cx).params; ).clean(self.cx).params;
Generics { Generics {
@ -489,7 +489,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let mut generic_params = ( let mut generic_params = (
tcx.generics_of(param_env_def_id), tcx.generics_of(param_env_def_id),
&tcx.explicit_predicates_of(param_env_def_id), tcx.explicit_predicates_of(param_env_def_id),
).clean(self.cx).params; ).clean(self.cx).params;
let mut has_sized = FxHashSet::default(); let mut has_sized = FxHashSet::default();

View file

@ -107,7 +107,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
unsafety: hir::Unsafety::Normal, unsafety: hir::Unsafety::Normal,
generics: ( generics: (
self.cx.tcx.generics_of(impl_def_id), self.cx.tcx.generics_of(impl_def_id),
&self.cx.tcx.explicit_predicates_of(impl_def_id), self.cx.tcx.explicit_predicates_of(impl_def_id),
).clean(self.cx), ).clean(self.cx),
provided_trait_methods, provided_trait_methods,
// FIXME(eddyb) compute both `trait_` and `for_` from // FIXME(eddyb) compute both `trait_` and `for_` from

View file

@ -193,7 +193,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
let auto_trait = cx.tcx.trait_def(did).has_auto_impl; let auto_trait = cx.tcx.trait_def(did).has_auto_impl;
let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect(); let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
let predicates = cx.tcx.predicates_of(did); let predicates = cx.tcx.predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
let generics = filter_non_trait_generics(did, generics); let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
let is_spotlight = load_attrs(cx, did).clean(cx).has_doc_flag(sym::spotlight); let is_spotlight = load_attrs(cx, did).clean(cx).has_doc_flag(sym::spotlight);
@ -220,7 +220,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
let asyncness = cx.tcx.asyncness(did); let asyncness = cx.tcx.asyncness(did);
let predicates = cx.tcx.predicates_of(did); let predicates = cx.tcx.predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, || { let (generics, decl) = clean::enter_impl_trait(cx, || {
((cx.tcx.generics_of(did), &predicates).clean(cx), (did, sig).clean(cx)) ((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
}); });
let (all_types, ret_types) = clean::get_all_types(&generics, &decl, cx); let (all_types, ret_types) = clean::get_all_types(&generics, &decl, cx);
clean::Function { clean::Function {
@ -241,7 +241,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
let predicates = cx.tcx.explicit_predicates_of(did); let predicates = cx.tcx.explicit_predicates_of(did);
clean::Enum { clean::Enum {
generics: (cx.tcx.generics_of(did), &predicates).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx),
variants_stripped: false, variants_stripped: false,
variants: cx.tcx.adt_def(did).variants.clean(cx), variants: cx.tcx.adt_def(did).variants.clean(cx),
} }
@ -257,7 +257,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
CtorKind::Fn => doctree::Tuple, CtorKind::Fn => doctree::Tuple,
CtorKind::Const => doctree::Unit, CtorKind::Const => doctree::Unit,
}, },
generics: (cx.tcx.generics_of(did), &predicates).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx),
fields: variant.fields.clean(cx), fields: variant.fields.clean(cx),
fields_stripped: false, fields_stripped: false,
} }
@ -269,7 +269,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
clean::Union { clean::Union {
struct_type: doctree::Plain, struct_type: doctree::Plain,
generics: (cx.tcx.generics_of(did), &predicates).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx),
fields: variant.fields.clean(cx), fields: variant.fields.clean(cx),
fields_stripped: false, fields_stripped: false,
} }
@ -280,7 +280,7 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
clean::Typedef { clean::Typedef {
type_: cx.tcx.type_of(did).clean(cx), type_: cx.tcx.type_of(did).clean(cx),
generics: (cx.tcx.generics_of(did), &predicates).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx),
} }
} }
@ -376,7 +376,7 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, attrs: Option<Attrs<'_>>,
} }
}).collect::<Vec<_>>(), }).collect::<Vec<_>>(),
clean::enter_impl_trait(cx, || { clean::enter_impl_trait(cx, || {
(tcx.generics_of(did), &predicates).clean(cx) (tcx.generics_of(did), predicates).clean(cx)
}), }),
) )
}; };

View file

@ -1664,8 +1664,7 @@ impl Clean<Generics> for hir::Generics {
} }
} }
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) {
&'a &'tcx ty::GenericPredicates<'tcx>) {
fn clean(&self, cx: &DocContext<'_>) -> Generics { fn clean(&self, cx: &DocContext<'_>) -> Generics {
use self::WherePredicate as WP; use self::WherePredicate as WP;
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -2369,7 +2368,7 @@ impl Clean<Item> for ty::AssocItem {
} }
ty::AssocKind::Method => { ty::AssocKind::Method => {
let generics = (cx.tcx.generics_of(self.def_id), let generics = (cx.tcx.generics_of(self.def_id),
&cx.tcx.explicit_predicates_of(self.def_id)).clean(cx); cx.tcx.explicit_predicates_of(self.def_id)).clean(cx);
let sig = cx.tcx.fn_sig(self.def_id); let sig = cx.tcx.fn_sig(self.def_id);
let mut decl = (self.def_id, sig).clean(cx); let mut decl = (self.def_id, sig).clean(cx);
@ -2448,7 +2447,7 @@ impl Clean<Item> for ty::AssocItem {
// all of the generics from there and then look for bounds that are // all of the generics from there and then look for bounds that are
// applied to this associated type in question. // applied to this associated type in question.
let predicates = cx.tcx.explicit_predicates_of(did); let predicates = cx.tcx.explicit_predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx); let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
let mut bounds = generics.where_predicates.iter().filter_map(|pred| { let mut bounds = generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred { let (name, self_type, trait_, bounds) = match *pred {
WherePredicate::BoundPredicate { WherePredicate::BoundPredicate {