From cd9e4441eb55135b452689abe54ce9fb0c72f90b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Oct 2019 03:14:57 +0300 Subject: [PATCH] rustc: arena-allocate the slice in `ty::GenericsPredicate`, not the whole struct. --- src/librustc/arena.rs | 1 - src/librustc/query/mod.rs | 13 ++-- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/ty/codec.rs | 35 ++++++---- src/librustc/ty/context.rs | 14 ---- src/librustc/ty/mod.rs | 11 ++- src/librustc/ty/query/on_disk_cache.rs | 7 +- src/librustc/ty/structural_impls.rs | 6 -- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 8 +-- src/librustc_metadata/encoder.rs | 14 ++-- .../transform/qualify_min_const_fn.rs | 2 +- src/librustc_privacy/lib.rs | 4 +- src/librustc_traits/lowering/mod.rs | 4 +- src/librustc_typeck/astconv.rs | 3 +- src/librustc_typeck/check/dropck.rs | 6 +- src/librustc_typeck/check/mod.rs | 16 ++--- src/librustc_typeck/check/wfcheck.rs | 4 +- src/librustc_typeck/collect.rs | 69 +++++++++++-------- .../constrained_generic_params.rs | 4 +- src/librustc_typeck/impl_wf_check.rs | 2 +- src/librustc_typeck/outlives/explicit.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 4 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 14 ++-- src/librustdoc/clean/mod.rs | 7 +- 27 files changed, 120 insertions(+), 138 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 5a5919d786638..3daf0fc9df7a0 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -98,7 +98,6 @@ macro_rules! arena_types { rustc::hir::def_id::DefId, >, [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes, - [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>, [few] lint_levels: rustc::lint::LintLevelMap, [few] stability_index: rustc::middle::stability::Index<'tcx>, [few] features: syntax::feature_gate::Features, diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 2a012c5274191..2c407a24493ff 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -61,7 +61,7 @@ rustc_queries! { /// predicate gets in the way of some checks, which are intended /// to operate over only the actual where-clauses written by the /// 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() } } @@ -184,12 +184,10 @@ rustc_queries! { /// predicates (where-clauses) directly defined on it. This is /// equal to the `explicit_predicates_of` predicates plus the /// `inferred_outlives_of` predicates. - query predicates_defined_on(_: DefId) - -> &'tcx ty::GenericPredicates<'tcx> {} + query predicates_defined_on(_: DefId) -> ty::GenericPredicates<'tcx> {} /// Returns the predicates written explicitly by the user. - query explicit_predicates_of(_: DefId) - -> &'tcx ty::GenericPredicates<'tcx> {} + query explicit_predicates_of(_: DefId) -> ty::GenericPredicates<'tcx> {} /// Returns the inferred outlives predicates (e.g., for `struct /// 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 /// full predicates are available (note that supertraits have /// 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) } } /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. - query type_param_predicates(key: (DefId, DefId)) - -> &'tcx ty::GenericPredicates<'tcx> { + query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> { no_force desc { |tcx| "computing the bounds for type parameter `{}`", { let id = tcx.hir().as_local_hir_id(key.1).unwrap(); diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 9c80ef7d4a23e..c1c6eb850f591 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -419,7 +419,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option // The predicates will contain default bounds like `T: Sized`. We need to // 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( predicates.len() + types_without_default_bounds.len()); diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index bd4913c88fd1f..03cb4775bd83f 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -16,6 +16,7 @@ use std::intrinsics; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; use crate::mir::interpret::Allocation; +use syntax_pos::Span; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. @@ -92,16 +93,16 @@ pub fn encode_with_shorthand(encoder: &mut E, Ok(()) } -pub fn encode_predicates<'tcx, E, C>(encoder: &mut E, - predicates: &ty::GenericPredicates<'tcx>, - cache: C) - -> Result<(), E::Error> +pub fn encode_spanned_predicates<'tcx, E, C>( + encoder: &mut E, + predicates: &'tcx [(ty::Predicate<'tcx>, Span)], + cache: C, +) -> Result<(), E::Error> where E: TyEncoder, C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, usize>, { - predicates.parent.encode(encoder)?; - predicates.predicates.len().encode(encoder)?; - for (predicate, span) in &predicates.predicates { + predicates.len().encode(encoder)?; + for (predicate, span) in predicates { encode_with_shorthand(encoder, predicate, &cache)?; span.encode(encoder)?; } @@ -182,13 +183,15 @@ where } #[inline] -pub fn decode_predicates(decoder: &mut D) -> Result, D::Error> +pub fn decode_spanned_predicates( + decoder: &mut D, +) -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], D::Error> where D: TyDecoder<'tcx>, { - Ok(ty::GenericPredicates { - parent: Decodable::decode(decoder)?, - predicates: (0..decoder.read_usize()?).map(|_| { + let tcx = decoder.tcx(); + Ok(tcx.arena.alloc_from_iter( + (0..decoder.read_usize()?).map(|_| { // Handle shorthands first, if we have an usize > 0x80. let predicate = if decoder.positioned_at_shorthand() { let pos = decoder.read_usize()?; @@ -202,7 +205,7 @@ where Ok((predicate, Decodable::decode(decoder)?)) }) .collect::, _>>()?, - }) + )) } #[inline] @@ -339,6 +342,8 @@ macro_rules! implement_ty_decoder { use $crate::ty::subst::SubstsRef; use $crate::hir::def_id::{CrateNum}; + use syntax_pos::Span; + use super::$DecoderName; impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> { @@ -393,11 +398,11 @@ macro_rules! implement_ty_decoder { } } - impl<$($typaram),*> SpecializedDecoder> + impl<$($typaram),*> SpecializedDecoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for $DecoderName<$($typaram),*> { fn specialized_decode(&mut self) - -> Result, Self::Error> { - decode_predicates(self) + -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], Self::Error> { + decode_spanned_predicates(self) } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 256194cfb00ef..665d4c2d0696a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -148,10 +148,6 @@ impl<'tcx> CtxtInterners<'tcx> { } } -pub struct Common<'tcx> { - pub empty_predicates: ty::GenericPredicates<'tcx>, -} - pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, pub bool: Ty<'tcx>, @@ -1039,9 +1035,6 @@ pub struct GlobalCtxt<'tcx> { pub prof: SelfProfilerRef, - /// Common objects. - pub common: Common<'tcx>, - /// Common types, pre-interned for your convenience. pub types: CommonTypes<'tcx>, @@ -1213,12 +1206,6 @@ impl<'tcx> TyCtxt<'tcx> { s.fatal(&err); }); 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_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -1273,7 +1260,6 @@ impl<'tcx> TyCtxt<'tcx> { interners, dep_graph, prof: s.prof.clone(), - common, types: common_types, lifetimes: common_lifetimes, consts: common_consts, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d5911a24de21a..14f0c3284fcb7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1018,15 +1018,12 @@ impl<'tcx> Generics { } /// Bounds on generics. -#[derive(Clone, Default, Debug, HashStable)] +#[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, - 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> { pub fn instantiate( &self, @@ -2321,7 +2318,7 @@ impl<'tcx> AdtDef { } #[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) } @@ -2561,7 +2558,7 @@ impl<'tcx> AdtDef { def_id: sized_trait, substs: tcx.mk_substs_trait(ty, &[]) }).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) { vec![] } else { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 1bba7fdd863ea..21a7cf00b283f 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -882,15 +882,16 @@ where } } -impl<'a, 'tcx, E> SpecializedEncoder> for CacheEncoder<'a, 'tcx, E> +impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> + for CacheEncoder<'a, 'tcx, E> where E: 'a + TyEncoder, { #[inline] fn specialized_encode(&mut self, - predicates: &ty::GenericPredicates<'tcx>) + predicates: &&'tcx [(ty::Predicate<'tcx>, Span)]) -> Result<(), Self::Error> { - ty_codec::encode_predicates(self, predicates, + ty_codec::encode_spanned_predicates(self, predicates, |encoder| &mut encoder.predicate_shorthands) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 8945e1a1debdb..83ec98f9ddd2f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -1218,12 +1218,6 @@ EnumTypeFoldableImpl! { } } -BraceStructTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { - parent, predicates - } -} - impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { // This code is hot enough that it's worth specializing for a list of diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 9a16d0a0715f7..08f6f43ab0cff 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1241,7 +1241,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { if cx.tcx.features().trivial_bounds { let def_id = cx.tcx.hir().local_def_id(item.hir_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 { Trait(..) => "Trait", TypeOutlives(..) | diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 3b3995832cb4c..a93946df68f92 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -156,7 +156,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } ty::Opaque(def, _) => { 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 { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index fd011265da7cb..4cd1ff7b4a4ff 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -97,11 +97,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, generics_of => { tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess)) } - predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) } - predicates_defined_on => { - tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx)) - } - super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) } + 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.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess)) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index f1436e4c09dff..ce4969146135b 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -243,11 +243,11 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { } } -impl<'tcx> SpecializedEncoder> for EncodeContext<'tcx> { +impl<'tcx> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for EncodeContext<'tcx> { fn specialized_encode(&mut self, - predicates: &ty::GenericPredicates<'tcx>) + predicates: &&'tcx [(ty::Predicate<'tcx>, Span)]) -> 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) { 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) { debug!("EncodeContext::encode_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) { @@ -1166,14 +1166,14 @@ impl EncodeContext<'tcx> { paren_sugar: trait_def.paren_sugar, has_auto_impl: self.tcx.trait_is_auto(def_id), 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)) } hir::ItemKind::TraitAlias(..) => { 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)) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index cf0ee1bf09222..7b6255defd148 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -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; loop { let predicates = tcx.predicates_of(current); - for (predicate, _) in &predicates.predicates { + for (predicate, _) in predicates.predicates { match predicate { | Predicate::RegionOutlives(_) | Predicate::TypeOutlives(_) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f44692b7aea7d..eb79ce69a3e1f 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -64,7 +64,7 @@ trait DefIdVisitor<'tcx> { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool { 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) } } @@ -88,7 +88,7 @@ where (!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; for (predicate, _span) in predicates { match predicate { diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 4c30227150fb1..0df367fcca83c 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -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 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, // 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(); // `WC` - let predicates = &tcx.predicates_of(def_id).predicates; + let predicates = tcx.predicates_of(def_id).predicates; let where_clauses = predicates .iter() .map(|(wc, _)| wc.lower()) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b8e2700803a5d..7e0a9bc4011c0 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -54,8 +54,7 @@ pub trait AstConv<'tcx> { /// but this can lead to cycle errors. The problem is that we have /// to do this resolution *in order to create the predicates in /// the first place*. Hence, we have this "special pass". - fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> &'tcx ty::GenericPredicates<'tcx>; + fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx>; /// Returns the lifetime to use when a lifetime is omitted (and not elided). fn re_infer( diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index d46ac4a39a337..0c8df9bad448f 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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( tcx, drop_impl_did, - &dtor_predicates, + dtor_predicates, adt_def.did, 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>( tcx: TyCtxt<'tcx>, drop_impl_did: DefId, - dtor_predicates: &ty::GenericPredicates<'tcx>, + dtor_predicates: ty::GenericPredicates<'tcx>, self_type_did: DefId, self_to_impl_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorReported> { @@ -199,7 +199,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( // just to look for all the predicates directly. 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 // expressions etc because the Drop impls are already forced // to take on a structure that is roughly an alpha-renaming of diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7475b9cc3b327..152edf8dd0e5a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2245,19 +2245,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { self.tcx } - fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) - -> &'tcx ty::GenericPredicates<'tcx> - { + fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> { let tcx = self.tcx; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item_id = tcx.hir().ty_param_owner(hir_id); let item_def_id = tcx.hir().local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - tcx.arena.alloc(ty::GenericPredicates { + ty::GenericPredicates { parent: None, - predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { - match predicate { + predicates: tcx.arena.alloc_from_iter( + self.param_env.caller_bounds.iter().filter_map(|&predicate| match predicate { ty::Predicate::Trait(ref data) if data.skip_binder().self_ty().is_param(index) => { // HACK(eddyb) should get the original `Span`. @@ -2265,9 +2263,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { Some((predicate, span)) } _ => None - } - }).collect() - }) + }), + ), + } } fn re_infer( diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index fa283904fe474..18b103960c745 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -791,7 +791,7 @@ fn check_opaque_types<'fcx, 'tcx>( "check_opaque_types: may define, predicates={:#?}", predicates, ); - for &(pred, _) in predicates.predicates.iter() { + for &(pred, _) in predicates.predicates { let substituted_pred = pred.subst(fcx.tcx, substs); // Avoid duplication of predicates that contain no parameters, for example. if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { @@ -1011,7 +1011,7 @@ fn check_variances_for_type_defn<'tcx>( identify_constrained_generic_params( tcx, - &ty_predicates, + ty_predicates, None, &mut constrained_parameters, ); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 5b2081bef78dc..1749fd1075e05 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -182,8 +182,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { self.tcx } - fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> &'tcx ty::GenericPredicates<'tcx> { + fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> { self.tcx .at(span) .type_param_predicates((self.item_def_id, def_id)) @@ -254,7 +253,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { fn type_param_predicates( tcx: TyCtxt<'_>, (item_def_id, def_id): (DefId, DefId), -) -> &ty::GenericPredicates<'_> { +) -> ty::GenericPredicates<'_> { use rustc::hir::*; // 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 }; - let result = parent.map_or(&tcx.common.empty_predicates, |parent| { + let mut result = parent.map(|parent| { let icx = ItemCtxt::new(tcx, parent); icx.get_type_parameter_bounds(DUMMY_SP, def_id) - }); + }).unwrap_or_default(); let mut extend = None; 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 mut result = (*result).clone(); - result.predicates.extend(extend.into_iter()); - result.predicates.extend( + let extra_predicates = extend.into_iter().chain( icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true)) .into_iter() .filter(|(predicate, _)| { @@ -331,9 +328,12 @@ fn type_param_predicates( ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index), _ => false, } - }) + }), + ); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.iter().copied().chain(extra_predicates), ); - tcx.arena.alloc(result) + result } impl ItemCtxt<'tcx> { @@ -698,7 +698,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef { fn super_predicates_of( tcx: TyCtxt<'_>, trait_def_id: DefId, -) -> &ty::GenericPredicates<'_> { +) -> ty::GenericPredicates<'_> { debug!("super_predicates(trait_def_id={:?})", trait_def_id); 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)); // 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, // which will, in turn, reach indirect supertraits. - for &(pred, span) in &superbounds { + for &(pred, span) in superbounds { debug!("superbound: {:?}", pred); if let ty::Predicate::Trait(bound) = pred { tcx.at(span).super_predicates_of(bound.def_id()); } } - tcx.arena.alloc(ty::GenericPredicates { + ty::GenericPredicates { parent: None, predicates: superbounds, - }) + } } 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( tcx: TyCtxt<'_>, def_id: DefId, -) -> &ty::GenericPredicates<'_> { +) -> ty::GenericPredicates<'_> { debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!( @@ -1974,9 +1976,13 @@ fn predicates_defined_on( def_id, inferred_outlives, ); - let mut predicates = (*result).clone(); - predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span))); - result = tcx.arena.alloc(predicates); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.iter().copied().chain( + // 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); result @@ -1985,7 +1991,7 @@ fn predicates_defined_on( /// 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 /// `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); 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 // that this is done. let span = tcx.def_span(def_id); - let mut predicates = (*result).clone(); - predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); - result = tcx.arena.alloc(predicates); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.iter().copied().chain( + std::iter::once((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)) + ), + ); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -2015,7 +2023,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> { fn explicit_predicates_of( tcx: TyCtxt<'_>, def_id: DefId, -) -> &ty::GenericPredicates<'_> { +) -> ty::GenericPredicates<'_> { use rustc::hir::*; 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. /// Preserving the order of insertion is important here so as not to break /// compile-fail UI tests. + // FIXME(eddyb) just use `IndexSet` from `indexmap`. struct UniquePredicates<'tcx> { predicates: Vec<(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); if impl_trait_fn.is_some() { // opaque types - return tcx.arena.alloc(ty::GenericPredicates { + return ty::GenericPredicates { parent: None, - predicates: bounds_predicates, - }); + predicates: tcx.arena.alloc_from_iter(bounds_predicates), + }; } else { // named opaque types 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, - predicates, - }); + predicates: tcx.arena.alloc_from_iter(predicates), + }; debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result); result } diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs index 31476eb731798..1fdf49fde55b5 100644 --- a/src/librustc_typeck/constrained_generic_params.rs +++ b/src/librustc_typeck/constrained_generic_params.rs @@ -86,11 +86,11 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { pub fn identify_constrained_generic_params<'tcx>( tcx: TyCtxt<'tcx>, - predicates: &ty::GenericPredicates<'tcx>, + predicates: ty::GenericPredicates<'tcx>, impl_trait_ref: Option>, input_parameters: &mut FxHashSet, ) { - let mut predicates = predicates.predicates.clone(); + let mut predicates = predicates.predicates.to_vec(); setup_constraining_predicates(tcx, &mut predicates, impl_trait_ref, input_parameters); } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index ab660caa222ae..2d188007712ad 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -114,7 +114,7 @@ fn enforce_impl_params_are_constrained( let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref); 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. let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() diff --git a/src/librustc_typeck/outlives/explicit.rs b/src/librustc_typeck/outlives/explicit.rs index 40a57788c0710..83194144216ee 100644 --- a/src/librustc_typeck/outlives/explicit.rs +++ b/src/librustc_typeck/outlives/explicit.rs @@ -30,7 +30,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { let mut required_predicates = RequiredPredicates::default(); // process predicates and convert to `RequiredPredicates` entry, see below - for (pred, _) in predicates.predicates.iter() { + for (pred, _) in predicates.predicates { match pred { ty::Predicate::TypeOutlives(predicate) => { let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder(); diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 18a84cd0eeb76..b7f5ed9d004d4 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // regardless of the choice of `T`. let params = ( self.cx.tcx.generics_of(param_env_def_id), - &&self.cx.tcx.common.empty_predicates, + ty::GenericPredicates::default(), ).clean(self.cx).params; Generics { @@ -489,7 +489,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { let mut generic_params = ( 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; let mut has_sized = FxHashSet::default(); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index afed11e7fab26..ff59dcab672f3 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { unsafety: hir::Unsafety::Normal, generics: ( 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), provided_trait_methods, // FIXME(eddyb) compute both `trait_` and `for_` from diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 532c5f67bf3ba..b3227c9f60029 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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 trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect(); 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, supertrait_bounds) = separate_supertrait_bounds(generics); 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 predicates = cx.tcx.predicates_of(did); 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); clean::Function { @@ -241,7 +241,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum { let predicates = cx.tcx.explicit_predicates_of(did); clean::Enum { - generics: (cx.tcx.generics_of(did), &predicates).clean(cx), + generics: (cx.tcx.generics_of(did), predicates).clean(cx), variants_stripped: false, 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::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_stripped: false, } @@ -269,7 +269,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union { clean::Union { 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_stripped: false, } @@ -280,7 +280,7 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef { clean::Typedef { 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>, } }).collect::>(), clean::enter_impl_trait(cx, || { - (tcx.generics_of(did), &predicates).clean(cx) + (tcx.generics_of(did), predicates).clean(cx) }), ) }; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 212a09ee6e634..d9c853aa7aa35 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1664,8 +1664,7 @@ impl Clean for hir::Generics { } } -impl<'a, 'tcx> Clean for (&'a ty::Generics, - &'a &'tcx ty::GenericPredicates<'tcx>) { +impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext<'_>) -> Generics { use self::WherePredicate as WP; use std::collections::BTreeMap; @@ -2369,7 +2368,7 @@ impl Clean for ty::AssocItem { } ty::AssocKind::Method => { 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 mut decl = (self.def_id, sig).clean(cx); @@ -2448,7 +2447,7 @@ impl Clean for ty::AssocItem { // all of the generics from there and then look for bounds that are // applied to this associated type in question. 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 (name, self_type, trait_, bounds) = match *pred { WherePredicate::BoundPredicate {