Skip to content

Commit 6db12d4

Browse files
committed
Add DepNode::TraitSelectSingle variant.
This avoids the need for a heap allocation in the common case where the `TraitSelect` has a single `D`.
1 parent a88145d commit 6db12d4

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

src/librustc/dep_graph/dep_node.rs

+6
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ pub enum DepNode<D: Clone + Debug> {
127127
TraitItems(D),
128128
ReprHints(D),
129129
TraitSelect(Vec<D>),
130+
131+
// An optional alternative to `TraitSelect` that avoids a heap allocation
132+
// in the case where there is a single D. (Note that `TraitSelect` is still
133+
// allowed to contain a Vec with a single D.)
134+
TraitSelectSingle(D),
130135
}
131136

132137
impl<D: Clone + Debug> DepNode<D> {
@@ -232,6 +237,7 @@ impl<D: Clone + Debug> DepNode<D> {
232237
let type_ds = try_opt!(type_ds.iter().map(|d| op(d)).collect());
233238
Some(TraitSelect(type_ds))
234239
}
240+
TraitSelectSingle(ref d) => op(d).map(TraitSelectSingle),
235241
}
236242
}
237243
}

src/librustc/ty/mod.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -873,18 +873,26 @@ impl<'tcx> TraitPredicate<'tcx> {
873873
// `Rc<u32>: SomeTrait`, and `(Vec<u32>, Rc<u32>): SomeTrait`.
874874
// Note that it's always sound to conflate dep-nodes, it just
875875
// leads to more recompilation.
876-
let def_ids: Vec<_> =
876+
//
877+
// This code is hot enough that it's worth going to some effort (i.e.
878+
// the peek()) to use `TraitSelectSingle` and avoid a heap allocation
879+
// when possible.
880+
let mut def_ids_base =
877881
self.input_types()
878882
.flat_map(|t| t.walk())
879883
.filter_map(|t| match t.sty {
880-
ty::TyAdt(adt_def, _) =>
881-
Some(adt_def.did),
882-
_ =>
883-
None
884+
ty::TyAdt(adt_def, _) => Some(adt_def.did),
885+
_ => None
884886
})
885-
.chain(iter::once(self.def_id()))
886-
.collect();
887-
DepNode::TraitSelect(def_ids)
887+
.peekable();
888+
if let Some(_) = def_ids_base.peek() {
889+
let def_ids = def_ids_base
890+
.chain(iter::once(self.def_id()))
891+
.collect();
892+
DepNode::TraitSelect(def_ids)
893+
} else {
894+
DepNode::TraitSelectSingle(self.def_id())
895+
}
888896
}
889897

890898
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {

src/librustc_trans/context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
209209
_ => None,
210210
})
211211
.collect();
212+
// This code is not hot so it's not worth detecting if
213+
// `TraitSelectSingle` could be used instead of `TraitSelect`.
212214
DepNode::TraitSelect(def_ids)
213215
}
214216
}

0 commit comments

Comments
 (0)