Skip to content

Commit

Permalink
Auto merge of rust-lang#77990 - bugadani:copies, r=lcnr
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Nov 13, 2020
2 parents 2c4df6b + f0d0d87 commit a1f7ca7
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 45 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ impl TokenStream {
}
}
if let Some((pos, comma, sp)) = suggestion {
let mut new_stream = vec![];
let mut new_stream = Vec::with_capacity(self.0.len() + 1);
let parts = self.0.split_at(pos + 1);
new_stream.extend_from_slice(parts.0);
new_stream.push(comma);
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1367,14 +1367,18 @@ impl<'hir> LoweringContext<'_, 'hir> {

let mut used_input_regs = FxHashMap::default();
let mut used_output_regs = FxHashMap::default();
let mut required_features: Vec<&str> = vec![];
for (idx, op) in operands.iter().enumerate() {
let op_sp = asm.operands[idx].1;
if let Some(reg) = op.reg() {
// Make sure we don't accidentally carry features from the
// previous iteration.
required_features.clear();

// Validate register classes against currently enabled target
// features. We check that at least one type is available for
// the current target.
let reg_class = reg.reg_class();
let mut required_features: Vec<&str> = vec![];
for &(_, feature) in reg_class.supported_types(asm_arch) {
if let Some(feature) = feature {
if self.sess.target_features.contains(&Symbol::intern(feature)) {
Expand Down
51 changes: 26 additions & 25 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2011,17 +2011,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
//
// For the "output" lifetime parameters, we just want to
// generate `'_`.
let mut generic_args: Vec<_> = lifetime_params[..input_lifetimes_count]
.iter()
.map(|&(span, hir_name)| {
let mut generic_args = Vec::with_capacity(lifetime_params.len());
generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
|&(span, hir_name)| {
// Input lifetime like `'a` or `'1`:
GenericArg::Lifetime(hir::Lifetime {
hir_id: self.next_id(),
span,
name: hir::LifetimeName::Param(hir_name),
})
})
.collect();
},
));
generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
// Output lifetime like `'_`.
GenericArg::Lifetime(hir::Lifetime {
Expand Down Expand Up @@ -2312,29 +2312,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}

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

for (index, stmt) in b.stmts.iter().enumerate() {
if index == b.stmts.len() - 1 {
if let StmtKind::Expr(ref e) = stmt.kind {
expr = Some(self.lower_expr(e));
} else {
stmts.extend(self.lower_stmt(stmt));
}
} else {
stmts.extend(self.lower_stmt(stmt));
}
}
let stmts = self.arena.alloc_from_iter(
b.stmts
.iter()
.enumerate()
.filter_map(|(index, stmt)| {
if index == b.stmts.len() - 1 {
if let StmtKind::Expr(ref e) = stmt.kind {
expr = Some(self.lower_expr(e));
None
} else {
Some(self.lower_stmt(stmt))
}
} else {
Some(self.lower_stmt(stmt))
}
})
.flatten(),
);
let rules = self.lower_block_check_mode(&b.rules);
let hir_id = self.lower_node_id(b.id);

hir::Block {
hir_id: self.lower_node_id(b.id),
stmts: self.arena.alloc_from_iter(stmts),
expr,
rules: self.lower_block_check_mode(&b.rules),
span: b.span,
targeted_by_break,
}
hir::Block { hir_id, stmts, expr, rules, span: b.span, targeted_by_break }
}

/// Lowers a block directly to an expression, presuming that it
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>

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

let mut stmts = vec![];
let mut stmts = Vec::with_capacity(fields.len() + 2);
match vdata {
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
// tuple struct/"normal" variant
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
let mut builder = LintLevelMapBuilder { levels, tcx, store };
let krate = tcx.hir().krate();

builder.levels.id_to_set.reserve(krate.exported_macros.len() + 1);

let push = builder.levels.push(&krate.item.attrs, &store, true);
builder.levels.register_id(hir::CRATE_HIR_ID);
for macro_def in krate.exported_macros {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,14 +784,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
};

let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
SyntaxExtension::new(
sess,
kind,
self.get_span(id, sess),
helper_attrs,
self.root.edition,
Symbol::intern(name),
&self.get_item_attrs(id, sess),
&attrs,
)
}

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

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

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

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

fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<Symbol>> {
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
}
item_attrs => { tcx.arena.alloc_from_iter(
cdata.get_item_attrs(def_id.index, tcx.sess).into_iter()
cdata.get_item_attrs(def_id.index, tcx.sess)
) }
fn_arg_names => { cdata.get_fn_param_names(tcx, def_id.index) }
rendered_const => { cdata.get_rendered_const(def_id.index) }
Expand Down Expand Up @@ -415,11 +415,7 @@ impl CStore {

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

// Mark the attrs as used
let attrs = data.get_item_attrs(id.index, sess);
for attr in attrs.iter() {
sess.mark_attr_used(attr);
}
let attrs = data.get_item_attrs(id.index, sess).collect();

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

Expand All @@ -428,7 +424,7 @@ impl CStore {
ident,
id: ast::DUMMY_NODE_ID,
span,
attrs: attrs.to_vec(),
attrs,
kind: ast::ItemKind::MacroDef(data.get_macro(id.index, sess)),
vis: ast::Visibility {
span: span.shrink_to_lo(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());

// Keep only those bounds which may apply, and propagate overflow if it occurs.
let mut param_candidates = vec![];
for bound in matching_bounds {
let wc = self.evaluate_where_clause(stack, bound)?;
if wc.may_apply() {
param_candidates.push(ParamCandidate(bound));
candidates.vec.push(ParamCandidate(bound));
}
}

candidates.vec.extend(param_candidates);

Ok(())
}

Expand Down

0 comments on commit a1f7ca7

Please sign in to comment.