Skip to content

Commit a1f7ca7

Browse files
committed
Auto merge of #77990 - bugadani:copies, r=lcnr
Eliminate some temporary vectors This PR changes `get_item_attrs` and `get_item_variances` to return iterator impls instead of vectors. On top of that, this PR replaces some seemingly unnecessary vectors with iterators or SmallVec, and also reserves space where we know (the minimum) number of elements that will be inserted. This change hopes to remove a few heap allocations and unnecessary copies.
2 parents 2c4df6b + f0d0d87 commit a1f7ca7

File tree

8 files changed

+50
-45
lines changed

8 files changed

+50
-45
lines changed

compiler/rustc_ast/src/tokenstream.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl TokenStream {
221221
}
222222
}
223223
if let Some((pos, comma, sp)) = suggestion {
224-
let mut new_stream = vec![];
224+
let mut new_stream = Vec::with_capacity(self.0.len() + 1);
225225
let parts = self.0.split_at(pos + 1);
226226
new_stream.extend_from_slice(parts.0);
227227
new_stream.push(comma);

compiler/rustc_ast_lowering/src/expr.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1367,14 +1367,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
13671367

13681368
let mut used_input_regs = FxHashMap::default();
13691369
let mut used_output_regs = FxHashMap::default();
1370+
let mut required_features: Vec<&str> = vec![];
13701371
for (idx, op) in operands.iter().enumerate() {
13711372
let op_sp = asm.operands[idx].1;
13721373
if let Some(reg) = op.reg() {
1374+
// Make sure we don't accidentally carry features from the
1375+
// previous iteration.
1376+
required_features.clear();
1377+
13731378
// Validate register classes against currently enabled target
13741379
// features. We check that at least one type is available for
13751380
// the current target.
13761381
let reg_class = reg.reg_class();
1377-
let mut required_features: Vec<&str> = vec![];
13781382
for &(_, feature) in reg_class.supported_types(asm_arch) {
13791383
if let Some(feature) = feature {
13801384
if self.sess.target_features.contains(&Symbol::intern(feature)) {

compiler/rustc_ast_lowering/src/lib.rs

+26-25
Original file line numberDiff line numberDiff line change
@@ -2011,17 +2011,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20112011
//
20122012
// For the "output" lifetime parameters, we just want to
20132013
// generate `'_`.
2014-
let mut generic_args: Vec<_> = lifetime_params[..input_lifetimes_count]
2015-
.iter()
2016-
.map(|&(span, hir_name)| {
2014+
let mut generic_args = Vec::with_capacity(lifetime_params.len());
2015+
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
2016+
|&(span, hir_name)| {
20172017
// Input lifetime like `'a` or `'1`:
20182018
GenericArg::Lifetime(hir::Lifetime {
20192019
hir_id: self.next_id(),
20202020
span,
20212021
name: hir::LifetimeName::Param(hir_name),
20222022
})
2023-
})
2024-
.collect();
2023+
},
2024+
));
20252025
generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
20262026
// Output lifetime like `'_`.
20272027
GenericArg::Lifetime(hir::Lifetime {
@@ -2312,29 +2312,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23122312
}
23132313

23142314
fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> {
2315-
let mut stmts = vec![];
23162315
let mut expr: Option<&'hir _> = None;
23172316

2318-
for (index, stmt) in b.stmts.iter().enumerate() {
2319-
if index == b.stmts.len() - 1 {
2320-
if let StmtKind::Expr(ref e) = stmt.kind {
2321-
expr = Some(self.lower_expr(e));
2322-
} else {
2323-
stmts.extend(self.lower_stmt(stmt));
2324-
}
2325-
} else {
2326-
stmts.extend(self.lower_stmt(stmt));
2327-
}
2328-
}
2317+
let stmts = self.arena.alloc_from_iter(
2318+
b.stmts
2319+
.iter()
2320+
.enumerate()
2321+
.filter_map(|(index, stmt)| {
2322+
if index == b.stmts.len() - 1 {
2323+
if let StmtKind::Expr(ref e) = stmt.kind {
2324+
expr = Some(self.lower_expr(e));
2325+
None
2326+
} else {
2327+
Some(self.lower_stmt(stmt))
2328+
}
2329+
} else {
2330+
Some(self.lower_stmt(stmt))
2331+
}
2332+
})
2333+
.flatten(),
2334+
);
2335+
let rules = self.lower_block_check_mode(&b.rules);
2336+
let hir_id = self.lower_node_id(b.id);
23292337

2330-
hir::Block {
2331-
hir_id: self.lower_node_id(b.id),
2332-
stmts: self.arena.alloc_from_iter(stmts),
2333-
expr,
2334-
rules: self.lower_block_check_mode(&b.rules),
2335-
span: b.span,
2336-
targeted_by_break,
2337-
}
2338+
hir::Block { hir_id, stmts, expr, rules, span: b.span, targeted_by_break }
23382339
}
23392340

23402341
/// Lowers a block directly to an expression, presuming that it

compiler/rustc_builtin_macros/src/deriving/debug.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
6666

6767
let fmt = substr.nonself_args[0].clone();
6868

69-
let mut stmts = vec![];
69+
let mut stmts = Vec::with_capacity(fields.len() + 2);
7070
match vdata {
7171
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
7272
// tuple struct/"normal" variant

compiler/rustc_lint/src/levels.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
3030
let mut builder = LintLevelMapBuilder { levels, tcx, store };
3131
let krate = tcx.hir().krate();
3232

33+
builder.levels.id_to_set.reserve(krate.exported_macros.len() + 1);
34+
3335
let push = builder.levels.push(&krate.item.attrs, &store, true);
3436
builder.levels.register_id(hir::CRATE_HIR_ID);
3537
for macro_def in krate.exported_macros {

compiler/rustc_metadata/src/rmeta/decoder.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -784,14 +784,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
784784
}
785785
};
786786

787+
let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
787788
SyntaxExtension::new(
788789
sess,
789790
kind,
790791
self.get_span(id, sess),
791792
helper_attrs,
792793
self.root.edition,
793794
Symbol::intern(name),
794-
&self.get_item_attrs(id, sess),
795+
&attrs,
795796
)
796797
}
797798

@@ -1157,7 +1158,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11571158
// within the crate. We only need this for fictive constructors,
11581159
// for other constructors correct visibilities
11591160
// were already encoded in metadata.
1160-
let attrs = self.get_item_attrs(def_id.index, sess);
1161+
let attrs: Vec<_> =
1162+
self.get_item_attrs(def_id.index, sess).collect();
11611163
if sess.contains_name(&attrs, sym::non_exhaustive) {
11621164
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
11631165
vis = ty::Visibility::Restricted(crate_def_id);
@@ -1283,8 +1285,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12831285
}
12841286
}
12851287

1286-
fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
1287-
self.root.tables.variances.get(self, id).unwrap_or_else(Lazy::empty).decode(self).collect()
1288+
fn get_item_variances(&'a self, id: DefIndex) -> impl Iterator<Item = ty::Variance> + 'a {
1289+
self.root.tables.variances.get(self, id).unwrap_or_else(Lazy::empty).decode(self)
12881290
}
12891291

12901292
fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
@@ -1308,7 +1310,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13081310
}
13091311
}
13101312

1311-
fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Vec<ast::Attribute> {
1313+
fn get_item_attrs(
1314+
&'a self,
1315+
node_id: DefIndex,
1316+
sess: &'a Session,
1317+
) -> impl Iterator<Item = ast::Attribute> + 'a {
13121318
// The attributes for a tuple struct/variant are attached to the definition, not the ctor;
13131319
// we assume that someone passing in a tuple struct ctor is actually wanting to
13141320
// look at the definition
@@ -1325,7 +1331,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13251331
.get(self, item_id)
13261332
.unwrap_or_else(Lazy::empty)
13271333
.decode((self, sess))
1328-
.collect::<Vec<_>>()
13291334
}
13301335

13311336
fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<Symbol>> {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
138138
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
139139
}
140140
item_attrs => { tcx.arena.alloc_from_iter(
141-
cdata.get_item_attrs(def_id.index, tcx.sess).into_iter()
141+
cdata.get_item_attrs(def_id.index, tcx.sess)
142142
) }
143143
fn_arg_names => { cdata.get_fn_param_names(tcx, def_id.index) }
144144
rendered_const => { cdata.get_rendered_const(def_id.index) }
@@ -415,11 +415,7 @@ impl CStore {
415415

416416
let span = data.get_span(id.index, sess);
417417

418-
// Mark the attrs as used
419-
let attrs = data.get_item_attrs(id.index, sess);
420-
for attr in attrs.iter() {
421-
sess.mark_attr_used(attr);
422-
}
418+
let attrs = data.get_item_attrs(id.index, sess).collect();
423419

424420
let ident = data.item_ident(id.index, sess);
425421

@@ -428,7 +424,7 @@ impl CStore {
428424
ident,
429425
id: ast::DUMMY_NODE_ID,
430426
span,
431-
attrs: attrs.to_vec(),
427+
attrs,
432428
kind: ast::ItemKind::MacroDef(data.get_macro(id.index, sess)),
433429
vis: ast::Visibility {
434430
span: span.shrink_to_lo(),

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -353,16 +353,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
353353
all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
354354

355355
// Keep only those bounds which may apply, and propagate overflow if it occurs.
356-
let mut param_candidates = vec![];
357356
for bound in matching_bounds {
358357
let wc = self.evaluate_where_clause(stack, bound)?;
359358
if wc.may_apply() {
360-
param_candidates.push(ParamCandidate(bound));
359+
candidates.vec.push(ParamCandidate(bound));
361360
}
362361
}
363362

364-
candidates.vec.extend(param_candidates);
365-
366363
Ok(())
367364
}
368365

0 commit comments

Comments
 (0)