Skip to content

Commit 98dab33

Browse files
committed
Wrap some query results in Lrc.
So that the frequent clones in `try_get` are cheaper. Fixes #54274.
1 parent 5c9f7dc commit 98dab33

File tree

14 files changed

+73
-69
lines changed

14 files changed

+73
-69
lines changed

src/librustc/infer/outlives/verify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,8 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
299299
let assoc_item = tcx.associated_item(assoc_item_def_id);
300300
let trait_def_id = assoc_item.container.assert_trait();
301301
let trait_predicates = tcx.predicates_of(trait_def_id).predicates
302-
.into_iter()
303-
.map(|(p, _)| p)
302+
.iter()
303+
.map(|(p, _)| *p)
304304
.collect();
305305
let identity_substs = Substs::identity_for_item(tcx, assoc_item_def_id);
306306
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);

src/librustc/traits/object_safety.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
182182
};
183183
predicates
184184
.predicates
185-
.into_iter()
185+
.iter()
186186
.map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref))
187187
.any(|predicate| {
188188
match predicate {
@@ -302,9 +302,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
302302
return Some(MethodViolationCode::Generic);
303303
}
304304

305-
if self.predicates_of(method.def_id).predicates.into_iter()
305+
if self.predicates_of(method.def_id).predicates.iter()
306306
// A trait object can't claim to live more than the concrete type,
307307
// so outlives predicates will always hold.
308+
.cloned()
308309
.filter(|(p, _)| p.to_opt_type_outlives().is_none())
309310
.collect::<Vec<_>>()
310311
// Do a shallow visit so that `contains_illegal_self_type_reference`

src/librustc/traits/specialize/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option<
407407

408408
// The predicates will contain default bounds like `T: Sized`. We need to
409409
// remove these bounds, and add `T: ?Sized` to any untouched type parameters.
410-
let predicates = tcx.predicates_of(impl_def_id).predicates;
410+
let predicates = &tcx.predicates_of(impl_def_id).predicates;
411411
let mut pretty_predicates = Vec::with_capacity(
412412
predicates.len() + types_without_default_bounds.len());
413413

src/librustc/ty/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2126,7 +2126,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
21262126
}
21272127

21282128
#[inline]
2129-
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> GenericPredicates<'gcx> {
2129+
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
21302130
tcx.predicates_of(self.did)
21312131
}
21322132

@@ -2369,8 +2369,8 @@ impl<'a, 'gcx, 'tcx> AdtDef {
23692369
def_id: sized_trait,
23702370
substs: tcx.mk_substs_trait(ty, &[])
23712371
}).to_predicate();
2372-
let predicates = tcx.predicates_of(self.did).predicates;
2373-
if predicates.into_iter().any(|(p, _)| p == sized_predicate) {
2372+
let predicates = &tcx.predicates_of(self.did).predicates;
2373+
if predicates.iter().any(|(p, _)| *p == sized_predicate) {
23742374
vec![]
23752375
} else {
23762376
vec![ty]

src/librustc/ty/query/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,18 @@ define_queries! { <'tcx>
127127
/// predicate gets in the way of some checks, which are intended
128128
/// to operate over only the actual where-clauses written by the
129129
/// user.)
130-
[] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
130+
[] fn predicates_of: PredicatesOfItem(DefId) -> Lrc<ty::GenericPredicates<'tcx>>,
131131

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

138139
/// Returns the predicates written explicit by the user.
139140
[] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId)
140-
-> ty::GenericPredicates<'tcx>,
141+
-> Lrc<ty::GenericPredicates<'tcx>>,
141142

142143
/// Returns the inferred outlives predicates (e.g., for `struct
143144
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
@@ -149,12 +150,12 @@ define_queries! { <'tcx>
149150
/// evaluate them even during type conversion, often before the
150151
/// full predicates are available (note that supertraits have
151152
/// additional acyclicity requirements).
152-
[] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
153+
[] fn super_predicates_of: SuperPredicatesOfItem(DefId) -> Lrc<ty::GenericPredicates<'tcx>>,
153154

154155
/// To avoid cycles within the predicates of a single item we compute
155156
/// per-type-parameter predicates for resolving `T::AssocTy`.
156157
[] fn type_param_predicates: type_param_predicates((DefId, DefId))
157-
-> ty::GenericPredicates<'tcx>,
158+
-> Lrc<ty::GenericPredicates<'tcx>>,
158159

159160
[] fn trait_def: TraitDefOfItem(DefId) -> &'tcx ty::TraitDef,
160161
[] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef,

src/librustc_metadata/cstore_impl.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
103103
generics_of => {
104104
tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
105105
}
106-
predicates_of => { cdata.get_predicates(def_id.index, tcx) }
107-
predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
108-
super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
106+
predicates_of => { Lrc::new(cdata.get_predicates(def_id.index, tcx)) }
107+
predicates_defined_on => { Lrc::new(cdata.get_predicates_defined_on(def_id.index, tcx)) }
108+
super_predicates_of => { Lrc::new(cdata.get_super_predicates(def_id.index, tcx)) }
109109
trait_def => {
110110
tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
111111
}

src/librustc_traits/lowering/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ fn program_clauses_for_trait<'a, 'tcx>(
217217

218218
let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env));
219219

220-
let where_clauses = &tcx.predicates_defined_on(def_id).predicates
221-
.into_iter()
220+
let predicates = &tcx.predicates_defined_on(def_id).predicates;
221+
let where_clauses = &predicates
222+
.iter()
222223
.map(|(wc, _)| wc.lower())
223224
.map(|wc| wc.subst(tcx, bound_vars))
224225
.collect::<Vec<_>>();
@@ -314,8 +315,9 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
314315
let trait_pred = ty::TraitPredicate { trait_ref }.lower();
315316

316317
// `WC`
317-
let where_clauses = tcx.predicates_of(def_id).predicates
318-
.into_iter()
318+
let predicates = &tcx.predicates_of(def_id).predicates;
319+
let where_clauses = predicates
320+
.iter()
319321
.map(|(wc, _)| wc.lower())
320322
.map(|wc| wc.subst(tcx, bound_vars));
321323

@@ -352,7 +354,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
352354

353355
// `WC`
354356
let where_clauses = tcx.predicates_of(def_id).predicates
355-
.into_iter()
357+
.iter()
356358
.map(|(wc, _)| wc.lower())
357359
.map(|wc| wc.subst(tcx, bound_vars))
358360
.collect::<Vec<_>>();

src/librustc_typeck/astconv.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc::traits;
2424
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
2525
use rustc::ty::{GenericParamDef, GenericParamDefKind};
2626
use rustc::ty::wf::object_region_bounds;
27+
use rustc_data_structures::sync::Lrc;
2728
use rustc_target::spec::abi;
2829
use std::collections::BTreeSet;
2930
use std::slice;
@@ -45,7 +46,7 @@ pub trait AstConv<'gcx, 'tcx> {
4546
/// Returns the set of bounds in scope for the type parameter with
4647
/// the given id.
4748
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
48-
-> ty::GenericPredicates<'tcx>;
49+
-> Lrc<ty::GenericPredicates<'tcx>>;
4950

5051
/// What lifetime should we use when a lifetime is omitted (and not elided)?
5152
fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>)
@@ -1119,8 +1120,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
11191120
{
11201121
let tcx = self.tcx();
11211122

1122-
let bounds = self.get_type_parameter_bounds(span, ty_param_def_id)
1123-
.predicates.into_iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
1123+
let predicates = &self.get_type_parameter_bounds(span, ty_param_def_id).predicates;
1124+
let bounds = predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref());
11241125

11251126
// Check that there is exactly one way to find an associated type with the
11261127
// correct name.

src/librustc_typeck/check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1869,15 +1869,15 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
18691869
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
18701870

18711871
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
1872-
-> ty::GenericPredicates<'tcx>
1872+
-> Lrc<ty::GenericPredicates<'tcx>>
18731873
{
18741874
let tcx = self.tcx;
18751875
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
18761876
let item_id = tcx.hir.ty_param_owner(node_id);
18771877
let item_def_id = tcx.hir.local_def_id(item_id);
18781878
let generics = tcx.generics_of(item_def_id);
18791879
let index = generics.param_def_id_to_index[&def_id];
1880-
ty::GenericPredicates {
1880+
Lrc::new(ty::GenericPredicates {
18811881
parent: None,
18821882
predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
18831883
match predicate {
@@ -1890,7 +1890,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
18901890
_ => None
18911891
}
18921892
}).collect()
1893-
}
1893+
})
18941894
}
18951895

18961896
fn re_infer(&self, span: Span, def: Option<&ty::GenericParamDef>)

src/librustc_typeck/check/wfcheck.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -910,8 +910,8 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
910910

911911
let def_id = fcx.tcx.hir.local_def_id(id);
912912
let predicates = fcx.tcx.predicates_of(def_id).predicates
913-
.into_iter()
914-
.map(|(p, _)| p)
913+
.iter()
914+
.map(|(p, _)| *p)
915915
.collect();
916916
// Check elaborated bounds
917917
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);

src/librustc_typeck/collect.rs

+33-34
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
3939
use rustc::ty::{ReprOptions, ToPredicate};
4040
use rustc::util::captures::Captures;
4141
use rustc::util::nodemap::FxHashMap;
42+
use rustc_data_structures::sync::Lrc;
4243
use rustc_target::spec::abi;
4344

4445
use syntax::ast;
@@ -178,7 +179,8 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
178179
self.tcx
179180
}
180181

181-
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
182+
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
183+
-> Lrc<ty::GenericPredicates<'tcx>> {
182184
self.tcx
183185
.at(span)
184186
.type_param_predicates((self.item_def_id, def_id))
@@ -243,7 +245,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
243245
fn type_param_predicates<'a, 'tcx>(
244246
tcx: TyCtxt<'a, 'tcx, 'tcx>,
245247
(item_def_id, def_id): (DefId, DefId),
246-
) -> ty::GenericPredicates<'tcx> {
248+
) -> Lrc<ty::GenericPredicates<'tcx>> {
247249
use rustc::hir::*;
248250

249251
// In the AST, bounds can derive from two places. Either
@@ -264,11 +266,11 @@ fn type_param_predicates<'a, 'tcx>(
264266
tcx.generics_of(item_def_id).parent
265267
};
266268

267-
let mut result = parent.map_or(
268-
ty::GenericPredicates {
269+
let mut result = parent.map_or_else(
270+
|| Lrc::new(ty::GenericPredicates {
269271
parent: None,
270272
predicates: vec![],
271-
},
273+
}),
272274
|parent| {
273275
let icx = ItemCtxt::new(tcx, parent);
274276
icx.get_type_parameter_bounds(DUMMY_SP, def_id)
@@ -298,7 +300,7 @@ fn type_param_predicates<'a, 'tcx>(
298300
// Implied `Self: Trait` and supertrait bounds.
299301
if param_id == item_node_id {
300302
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
301-
result
303+
Lrc::make_mut(&mut result)
302304
.predicates
303305
.push((identity_trait_ref.to_predicate(), item.span));
304306
}
@@ -317,7 +319,7 @@ fn type_param_predicates<'a, 'tcx>(
317319
};
318320

319321
let icx = ItemCtxt::new(tcx, item_def_id);
320-
result
322+
Lrc::make_mut(&mut result)
321323
.predicates
322324
.extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty,
323325
OnlySelfBounds(true)));
@@ -685,7 +687,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
685687
fn super_predicates_of<'a, 'tcx>(
686688
tcx: TyCtxt<'a, 'tcx, 'tcx>,
687689
trait_def_id: DefId,
688-
) -> ty::GenericPredicates<'tcx> {
690+
) -> Lrc<ty::GenericPredicates<'tcx>> {
689691
debug!("super_predicates(trait_def_id={:?})", trait_def_id);
690692
let trait_node_id = tcx.hir.as_local_node_id(trait_def_id).unwrap();
691693

@@ -729,10 +731,10 @@ fn super_predicates_of<'a, 'tcx>(
729731
}
730732
}
731733

732-
ty::GenericPredicates {
734+
Lrc::new(ty::GenericPredicates {
733735
parent: None,
734736
predicates: superbounds,
735-
}
737+
})
736738
}
737739

738740
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>(
16051607
fn predicates_defined_on<'a, 'tcx>(
16061608
tcx: TyCtxt<'a, 'tcx, 'tcx>,
16071609
def_id: DefId,
1608-
) -> ty::GenericPredicates<'tcx> {
1609-
let explicit = tcx.explicit_predicates_of(def_id);
1610-
let span = tcx.def_span(def_id);
1611-
let predicates = explicit.predicates.into_iter().chain(
1612-
tcx.inferred_outlives_of(def_id).iter().map(|&p| (p, span))
1613-
).collect();
1614-
1615-
ty::GenericPredicates {
1616-
parent: explicit.parent,
1617-
predicates: predicates,
1610+
) -> Lrc<ty::GenericPredicates<'tcx>> {
1611+
let mut result = tcx.explicit_predicates_of(def_id);
1612+
let inferred_outlives = tcx.inferred_outlives_of(def_id);
1613+
if !inferred_outlives.is_empty() {
1614+
let span = tcx.def_span(def_id);
1615+
Lrc::make_mut(&mut result)
1616+
.predicates
1617+
.extend(inferred_outlives.iter().map(|&p| (p, span)));
16181618
}
1619+
result
16191620
}
16201621

16211622
fn predicates_of<'a, 'tcx>(
16221623
tcx: TyCtxt<'a, 'tcx, 'tcx>,
16231624
def_id: DefId,
1624-
) -> ty::GenericPredicates<'tcx> {
1625-
let ty::GenericPredicates {
1626-
parent,
1627-
mut predicates,
1628-
} = tcx.predicates_defined_on(def_id);
1625+
) -> Lrc<ty::GenericPredicates<'tcx>> {
1626+
let mut result = tcx.predicates_defined_on(def_id);
16291627

16301628
if tcx.is_trait(def_id) {
16311629
// For traits, add `Self: Trait` predicate. This is
@@ -1641,16 +1639,17 @@ fn predicates_of<'a, 'tcx>(
16411639
// used, and adding the predicate into this list ensures
16421640
// that this is done.
16431641
let span = tcx.def_span(def_id);
1644-
predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
1642+
Lrc::make_mut(&mut result)
1643+
.predicates
1644+
.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
16451645
}
1646-
1647-
ty::GenericPredicates { parent, predicates }
1646+
result
16481647
}
16491648

16501649
fn explicit_predicates_of<'a, 'tcx>(
16511650
tcx: TyCtxt<'a, 'tcx, 'tcx>,
16521651
def_id: DefId,
1653-
) -> ty::GenericPredicates<'tcx> {
1652+
) -> Lrc<ty::GenericPredicates<'tcx>> {
16541653
use rustc::hir::*;
16551654
use rustc_data_structures::fx::FxHashSet;
16561655

@@ -1761,10 +1760,10 @@ fn explicit_predicates_of<'a, 'tcx>(
17611760

17621761
if impl_trait_fn.is_some() {
17631762
// impl Trait
1764-
return ty::GenericPredicates {
1763+
return Lrc::new(ty::GenericPredicates {
17651764
parent: None,
17661765
predicates: bounds.predicates(tcx, opaque_ty),
1767-
};
1766+
});
17681767
} else {
17691768
// named existential types
17701769
predicates.extend(bounds.predicates(tcx, opaque_ty));
@@ -1794,7 +1793,7 @@ fn explicit_predicates_of<'a, 'tcx>(
17941793
// on a trait we need to add in the supertrait bounds and bounds found on
17951794
// associated types.
17961795
if let Some((_trait_ref, _)) = is_trait {
1797-
predicates.extend(tcx.super_predicates_of(def_id).predicates);
1796+
predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned());
17981797
}
17991798

18001799
// In default impls, we can assume that the self type implements
@@ -1971,10 +1970,10 @@ fn explicit_predicates_of<'a, 'tcx>(
19711970
);
19721971
}
19731972

1974-
ty::GenericPredicates {
1973+
Lrc::new(ty::GenericPredicates {
19751974
parent: generics.parent,
19761975
predicates,
1977-
}
1976+
})
19781977
}
19791978

19801979
pub enum SizedByDefault {

0 commit comments

Comments
 (0)