提交 98dab333 编写于 作者: N Nicholas Nethercote

Wrap some query results in `Lrc`.

So that the frequent clones in `try_get` are cheaper.

Fixes #54274.
上级 5c9f7dcd
...@@ -299,8 +299,8 @@ fn region_bounds_declared_on_associated_item( ...@@ -299,8 +299,8 @@ fn region_bounds_declared_on_associated_item(
let assoc_item = tcx.associated_item(assoc_item_def_id); let assoc_item = tcx.associated_item(assoc_item_def_id);
let trait_def_id = assoc_item.container.assert_trait(); let trait_def_id = assoc_item.container.assert_trait();
let trait_predicates = tcx.predicates_of(trait_def_id).predicates let trait_predicates = tcx.predicates_of(trait_def_id).predicates
.into_iter() .iter()
.map(|(p, _)| p) .map(|(p, _)| *p)
.collect(); .collect();
let identity_substs = Substs::identity_for_item(tcx, assoc_item_def_id); let identity_substs = Substs::identity_for_item(tcx, assoc_item_def_id);
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs); let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
......
...@@ -182,7 +182,7 @@ fn predicates_reference_self( ...@@ -182,7 +182,7 @@ fn predicates_reference_self(
}; };
predicates predicates
.predicates .predicates
.into_iter() .iter()
.map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref)) .map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref))
.any(|predicate| { .any(|predicate| {
match predicate { match predicate {
...@@ -302,9 +302,10 @@ fn virtual_call_violation_for_method(self, ...@@ -302,9 +302,10 @@ fn virtual_call_violation_for_method(self,
return Some(MethodViolationCode::Generic); return Some(MethodViolationCode::Generic);
} }
if self.predicates_of(method.def_id).predicates.into_iter() if self.predicates_of(method.def_id).predicates.iter()
// A trait object can't claim to live more than the concrete type, // A trait object can't claim to live more than the concrete type,
// so outlives predicates will always hold. // so outlives predicates will always hold.
.cloned()
.filter(|(p, _)| p.to_opt_type_outlives().is_none()) .filter(|(p, _)| p.to_opt_type_outlives().is_none())
.collect::<Vec<_>>() .collect::<Vec<_>>()
// Do a shallow visit so that `contains_illegal_self_type_reference` // Do a shallow visit so that `contains_illegal_self_type_reference`
......
...@@ -407,7 +407,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< ...@@ -407,7 +407,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 // 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());
......
...@@ -2126,7 +2126,7 @@ pub fn non_enum_variant(&self) -> &VariantDef { ...@@ -2126,7 +2126,7 @@ pub fn non_enum_variant(&self) -> &VariantDef {
} }
#[inline] #[inline]
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> { pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
tcx.predicates_of(self.did) tcx.predicates_of(self.did)
} }
...@@ -2369,8 +2369,8 @@ fn sized_constraint_for_ty(&self, ...@@ -2369,8 +2369,8 @@ fn sized_constraint_for_ty(&self,
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.into_iter().any(|(p, _)| p == sized_predicate) { if predicates.iter().any(|(p, _)| *p == sized_predicate) {
vec![] vec![]
} else { } else {
vec![ty] vec![ty]
......
...@@ -127,17 +127,18 @@ ...@@ -127,17 +127,18 @@
/// 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.)
[] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>, [] fn predicates_of: PredicatesOfItem(DefId) -> Lrc<ty::GenericPredicates<'tcx>>,
/// Maps from the def-id of an item (trait/struct/enum/fn) to the /// Maps from the def-id of an item (trait/struct/enum/fn) to the
/// 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.
[] fn predicates_defined_on: PredicatesDefinedOnItem(DefId) -> ty::GenericPredicates<'tcx>, [] fn predicates_defined_on: PredicatesDefinedOnItem(DefId)
-> Lrc<ty::GenericPredicates<'tcx>>,
/// Returns the predicates written explicit by the user. /// Returns the predicates written explicit by the user.
[] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) [] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId)
-> ty::GenericPredicates<'tcx>, -> Lrc<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`).
...@@ -149,12 +150,12 @@ ...@@ -149,12 +150,12 @@
/// 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).
[] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>, [] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> Lrc<ty::GenericPredicates<'tcx>>,
/// 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`.
[] fn type_param_predicates: type_param_predicates((DefId, DefId)) [] fn type_param_predicates: type_param_predicates((DefId, DefId))
-> ty::GenericPredicates<'tcx>, -> Lrc<ty::GenericPredicates<'tcx>>,
[] fn trait_def: TraitDefOfItem(DefId) -> &'tcx ty::TraitDef, [] fn trait_def: TraitDefOfItem(DefId) -> &'tcx ty::TraitDef,
[] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef, [] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef,
......
...@@ -103,9 +103,9 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) } ...@@ -103,9 +103,9 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
generics_of => { generics_of => {
tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess)) tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
} }
predicates_of => { cdata.get_predicates(def_id.index, tcx) } predicates_of => { Lrc::new(cdata.get_predicates(def_id.index, tcx)) }
predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) } predicates_defined_on => { Lrc::new(cdata.get_predicates_defined_on(def_id.index, tcx)) }
super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) } super_predicates_of => { Lrc::new(cdata.get_super_predicates(def_id.index, tcx)) }
trait_def => { trait_def => {
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess)) tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
} }
......
...@@ -217,8 +217,9 @@ fn program_clauses_for_trait<'a, 'tcx>( ...@@ -217,8 +217,9 @@ fn program_clauses_for_trait<'a, 'tcx>(
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 where_clauses = &tcx.predicates_defined_on(def_id).predicates let predicates = &tcx.predicates_defined_on(def_id).predicates;
.into_iter() let where_clauses = &predicates
.iter()
.map(|(wc, _)| wc.lower()) .map(|(wc, _)| wc.lower())
.map(|wc| wc.subst(tcx, bound_vars)) .map(|wc| wc.subst(tcx, bound_vars))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
...@@ -314,8 +315,9 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId ...@@ -314,8 +315,9 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
let trait_pred = ty::TraitPredicate { trait_ref }.lower(); let trait_pred = ty::TraitPredicate { trait_ref }.lower();
// `WC` // `WC`
let where_clauses = tcx.predicates_of(def_id).predicates let predicates = &tcx.predicates_of(def_id).predicates;
.into_iter() let where_clauses = predicates
.iter()
.map(|(wc, _)| wc.lower()) .map(|(wc, _)| wc.lower())
.map(|wc| wc.subst(tcx, bound_vars)); .map(|wc| wc.subst(tcx, bound_vars));
...@@ -352,7 +354,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>( ...@@ -352,7 +354,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
// `WC` // `WC`
let where_clauses = tcx.predicates_of(def_id).predicates let where_clauses = tcx.predicates_of(def_id).predicates
.into_iter() .iter()
.map(|(wc, _)| wc.lower()) .map(|(wc, _)| wc.lower())
.map(|wc| wc.subst(tcx, bound_vars)) .map(|wc| wc.subst(tcx, bound_vars))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::{GenericParamDef, GenericParamDefKind};
use rustc::ty::wf::object_region_bounds; use rustc::ty::wf::object_region_bounds;
use rustc_data_structures::sync::Lrc;
use rustc_target::spec::abi; use rustc_target::spec::abi;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::slice; use std::slice;
...@@ -45,7 +46,7 @@ pub trait AstConv<'gcx, 'tcx> { ...@@ -45,7 +46,7 @@ pub trait AstConv<'gcx, 'tcx> {
/// Returns the set of bounds in scope for the type parameter with /// Returns the set of bounds in scope for the type parameter with
/// the given id. /// the given id.
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>; -> Lrc<ty::GenericPredicates<'tcx>>;
/// What lifetime should we use when a lifetime is omitted (and not elided)? /// What lifetime should we use when a lifetime is omitted (and not elided)?
fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>) fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>)
...@@ -1119,8 +1120,8 @@ fn find_bound_for_assoc_item(&self, ...@@ -1119,8 +1120,8 @@ fn find_bound_for_assoc_item(&self,
{ {
let tcx = self.tcx(); let tcx = self.tcx();
let bounds = self.get_type_parameter_bounds(span, ty_param_def_id) let predicates = &self.get_type_parameter_bounds(span, ty_param_def_id).predicates;
.predicates.into_iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()); let bounds = predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
// Check that there is exactly one way to find an associated type with the // Check that there is exactly one way to find an associated type with the
// correct name. // correct name.
......
...@@ -1869,7 +1869,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { ...@@ -1869,7 +1869,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, '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> -> Lrc<ty::GenericPredicates<'tcx>>
{ {
let tcx = self.tcx; let tcx = self.tcx;
let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
...@@ -1877,7 +1877,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) ...@@ -1877,7 +1877,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
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];
ty::GenericPredicates { Lrc::new(ty::GenericPredicates {
parent: None, parent: None,
predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
match predicate { match predicate {
...@@ -1890,7 +1890,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) ...@@ -1890,7 +1890,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
_ => None _ => None
} }
}).collect() }).collect()
} })
} }
fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>) fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)
......
...@@ -910,8 +910,8 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( ...@@ -910,8 +910,8 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
let def_id = fcx.tcx.hir.local_def_id(id); let def_id = fcx.tcx.hir.local_def_id(id);
let predicates = fcx.tcx.predicates_of(def_id).predicates let predicates = fcx.tcx.predicates_of(def_id).predicates
.into_iter() .iter()
.map(|(p, _)| p) .map(|(p, _)| *p)
.collect(); .collect();
// Check elaborated bounds // Check elaborated bounds
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
use rustc::ty::{ReprOptions, ToPredicate}; use rustc::ty::{ReprOptions, ToPredicate};
use rustc::util::captures::Captures; use rustc::util::captures::Captures;
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_target::spec::abi; use rustc_target::spec::abi;
use syntax::ast; use syntax::ast;
...@@ -178,7 +179,8 @@ fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { ...@@ -178,7 +179,8 @@ fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
self.tcx self.tcx
} }
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> { fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
-> Lrc<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))
...@@ -243,7 +245,7 @@ fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) { ...@@ -243,7 +245,7 @@ fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
fn type_param_predicates<'a, 'tcx>( fn type_param_predicates<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
(item_def_id, def_id): (DefId, DefId), (item_def_id, def_id): (DefId, DefId),
) -> ty::GenericPredicates<'tcx> { ) -> Lrc<ty::GenericPredicates<'tcx>> {
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
...@@ -264,11 +266,11 @@ fn type_param_predicates<'a, 'tcx>( ...@@ -264,11 +266,11 @@ fn type_param_predicates<'a, 'tcx>(
tcx.generics_of(item_def_id).parent tcx.generics_of(item_def_id).parent
}; };
let mut result = parent.map_or( let mut result = parent.map_or_else(
ty::GenericPredicates { || Lrc::new(ty::GenericPredicates {
parent: None, parent: None,
predicates: vec![], predicates: vec![],
}, }),
|parent| { |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)
...@@ -298,7 +300,7 @@ fn type_param_predicates<'a, 'tcx>( ...@@ -298,7 +300,7 @@ fn type_param_predicates<'a, 'tcx>(
// Implied `Self: Trait` and supertrait bounds. // Implied `Self: Trait` and supertrait bounds.
if param_id == item_node_id { if param_id == item_node_id {
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
result Lrc::make_mut(&mut result)
.predicates .predicates
.push((identity_trait_ref.to_predicate(), item.span)); .push((identity_trait_ref.to_predicate(), item.span));
} }
...@@ -317,7 +319,7 @@ fn type_param_predicates<'a, 'tcx>( ...@@ -317,7 +319,7 @@ fn type_param_predicates<'a, 'tcx>(
}; };
let icx = ItemCtxt::new(tcx, item_def_id); let icx = ItemCtxt::new(tcx, item_def_id);
result Lrc::make_mut(&mut result)
.predicates .predicates
.extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty,
OnlySelfBounds(true))); OnlySelfBounds(true)));
...@@ -685,7 +687,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad ...@@ -685,7 +687,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
fn super_predicates_of<'a, 'tcx>( fn super_predicates_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_def_id: DefId, trait_def_id: DefId,
) -> ty::GenericPredicates<'tcx> { ) -> Lrc<ty::GenericPredicates<'tcx>> {
debug!("super_predicates(trait_def_id={:?})", trait_def_id); debug!("super_predicates(trait_def_id={:?})", trait_def_id);
let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap(); let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
...@@ -729,10 +731,10 @@ fn super_predicates_of<'a, 'tcx>( ...@@ -729,10 +731,10 @@ fn super_predicates_of<'a, 'tcx>(
} }
} }
ty::GenericPredicates { Lrc::new(ty::GenericPredicates {
parent: None, parent: None,
predicates: superbounds, predicates: superbounds,
} })
} }
fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::TraitDef { fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::TraitDef {
...@@ -1605,27 +1607,23 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>( ...@@ -1605,27 +1607,23 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
fn predicates_defined_on<'a, 'tcx>( fn predicates_defined_on<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId, def_id: DefId,
) -> ty::GenericPredicates<'tcx> { ) -> Lrc<ty::GenericPredicates<'tcx>> {
let explicit = tcx.explicit_predicates_of(def_id); let mut result = tcx.explicit_predicates_of(def_id);
let span = tcx.def_span(def_id); let inferred_outlives = tcx.inferred_outlives_of(def_id);
let predicates = explicit.predicates.into_iter().chain( if !inferred_outlives.is_empty() {
tcx.inferred_outlives_of(def_id).iter().map(|&p| (p, span)) let span = tcx.def_span(def_id);
).collect(); Lrc::make_mut(&mut result)
.predicates
ty::GenericPredicates { .extend(inferred_outlives.iter().map(|&p| (p, span)));
parent: explicit.parent,
predicates: predicates,
} }
result
} }
fn predicates_of<'a, 'tcx>( fn predicates_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId, def_id: DefId,
) -> ty::GenericPredicates<'tcx> { ) -> Lrc<ty::GenericPredicates<'tcx>> {
let ty::GenericPredicates { let mut result = tcx.predicates_defined_on(def_id);
parent,
mut predicates,
} = tcx.predicates_defined_on(def_id);
if tcx.is_trait(def_id) { if tcx.is_trait(def_id) {
// For traits, add `Self: Trait` predicate. This is // For traits, add `Self: Trait` predicate. This is
...@@ -1641,16 +1639,17 @@ fn predicates_of<'a, 'tcx>( ...@@ -1641,16 +1639,17 @@ fn predicates_of<'a, 'tcx>(
// 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);
predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); Lrc::make_mut(&mut result)
.predicates
.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
} }
result
ty::GenericPredicates { parent, predicates }
} }
fn explicit_predicates_of<'a, 'tcx>( fn explicit_predicates_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId, def_id: DefId,
) -> ty::GenericPredicates<'tcx> { ) -> Lrc<ty::GenericPredicates<'tcx>> {
use rustc::hir::*; use rustc::hir::*;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
...@@ -1761,10 +1760,10 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: ...@@ -1761,10 +1760,10 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
if impl_trait_fn.is_some() { if impl_trait_fn.is_some() {
// impl Trait // impl Trait
return ty::GenericPredicates { return Lrc::new(ty::GenericPredicates {
parent: None, parent: None,
predicates: bounds.predicates(tcx, opaque_ty), predicates: bounds.predicates(tcx, opaque_ty),
}; });
} else { } else {
// named existential types // named existential types
predicates.extend(bounds.predicates(tcx, opaque_ty)); predicates.extend(bounds.predicates(tcx, opaque_ty));
...@@ -1794,7 +1793,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: ...@@ -1794,7 +1793,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
// on a trait we need to add in the supertrait bounds and bounds found on // on a trait we need to add in the supertrait bounds and bounds found on
// associated types. // associated types.
if let Some((_trait_ref, _)) = is_trait { if let Some((_trait_ref, _)) = is_trait {
predicates.extend(tcx.super_predicates_of(def_id).predicates); predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
} }
// In default impls, we can assume that the self type implements // In default impls, we can assume that the self type implements
...@@ -1971,10 +1970,10 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter: ...@@ -1971,10 +1970,10 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
); );
} }
ty::GenericPredicates { Lrc::new(ty::GenericPredicates {
parent: generics.parent, parent: generics.parent,
predicates, predicates,
} })
} }
pub enum SizedByDefault { pub enum SizedByDefault {
......
...@@ -33,14 +33,14 @@ pub fn explicit_predicates_of( ...@@ -33,14 +33,14 @@ pub fn explicit_predicates_of(
) -> &RequiredPredicates<'tcx> { ) -> &RequiredPredicates<'tcx> {
self.map.entry(def_id).or_insert_with(|| { self.map.entry(def_id).or_insert_with(|| {
let predicates = if def_id.is_local() { let predicates = if def_id.is_local() {
tcx.explicit_predicates_of(def_id).predicates tcx.explicit_predicates_of(def_id)
} else { } else {
tcx.predicates_of(def_id).predicates tcx.predicates_of(def_id)
}; };
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.into_iter() { for (pred, _) in predicates.predicates.iter() {
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();
......
...@@ -1563,7 +1563,7 @@ fn is_impl_trait(param: &hir::GenericParam) -> bool { ...@@ -1563,7 +1563,7 @@ fn is_impl_trait(param: &hir::GenericParam) -> bool {
} }
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
&'a ty::GenericPredicates<'tcx>) { &'a Lrc<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;
......
...@@ -156,8 +156,8 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId, ...@@ -156,8 +156,8 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId,
if child == trait_ { if child == trait_ {
return true return true
} }
let predicates = cx.tcx.super_predicates_of(child).predicates; let predicates = cx.tcx.super_predicates_of(child);
predicates.iter().filter_map(|(pred, _)| { predicates.predicates.iter().filter_map(|(pred, _)| {
if let ty::Predicate::Trait(ref pred) = *pred { if let ty::Predicate::Trait(ref pred) = *pred {
if pred.skip_binder().trait_ref.self_ty().is_self() { if pred.skip_binder().trait_ref.self_ty().is_self() {
Some(pred.def_id()) Some(pred.def_id())
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册