Skip to content

Commit e5eef19

Browse files
committed
Optimization in macro derive
More minor opts Rm unnecessary boxes
1 parent 206ee1e commit e5eef19

File tree

6 files changed

+127
-133
lines changed

6 files changed

+127
-133
lines changed

compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@ pub fn expand_deriving_partial_ord(
3838
}
3939

4040
let ordering_ty = Literal(path_std!(cmp::Ordering));
41-
let ret_ty = Literal(Path::new_(
42-
pathvec_std!(option::Option),
43-
None,
44-
vec![Box::new(ordering_ty)],
45-
PathKind::Std,
46-
));
41+
let ret_ty =
42+
Literal(Path::new_(pathvec_std!(option::Option), None, vec![ordering_ty], PathKind::Std));
4743

4844
let inline = cx.meta_word(span, sym::inline);
4945
let attrs = vec![cx.attribute(inline)];

compiler/rustc_builtin_macros/src/deriving/decodable.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,8 @@ pub fn expand_deriving_rustc_decodable(
4545
pathvec_std!(result::Result),
4646
None,
4747
vec![
48-
Box::new(Self_),
49-
Box::new(Literal(Path::new_(
50-
vec![typaram, sym::Error],
51-
None,
52-
vec![],
53-
PathKind::Local,
54-
))),
48+
Self_,
49+
Literal(Path::new_(vec![typaram, sym::Error], None, vec![], PathKind::Local)),
5550
],
5651
PathKind::Std,
5752
)),

compiler/rustc_builtin_macros/src/deriving/encodable.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,8 @@ pub fn expand_deriving_rustc_encodable(
135135
pathvec_std!(result::Result),
136136
None,
137137
vec![
138-
Box::new(Tuple(Vec::new())),
139-
Box::new(Literal(Path::new_(
140-
vec![typaram, sym::Error],
141-
None,
142-
vec![],
143-
PathKind::Local,
144-
))),
138+
Tuple(Vec::new()),
139+
Literal(Path::new_(vec![typaram, sym::Error], None, vec![], PathKind::Local)),
145140
],
146141
PathKind::Std,
147142
)),

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+97-88
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,15 @@ pub struct TraitDef<'a> {
212212
/// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
213213
pub generics: Bounds,
214214

215+
pub methods: Vec<MethodDef<'a>>,
216+
217+
pub associated_types: Vec<(Ident, Ty)>,
218+
215219
/// Is it an `unsafe` trait?
216220
pub is_unsafe: bool,
217221

218222
/// Can this trait be derived for unions?
219223
pub supports_unions: bool,
220-
221-
pub methods: Vec<MethodDef<'a>>,
222-
223-
pub associated_types: Vec<(Ident, Ty)>,
224224
}
225225

226226
pub struct MethodDef<'a> {
@@ -237,18 +237,18 @@ pub struct MethodDef<'a> {
237237
/// Arguments other than the self argument
238238
pub args: Vec<(Ty, Symbol)>,
239239

240-
/// Returns type
240+
/// Return type
241241
pub ret_ty: Ty,
242242

243243
pub attributes: Vec<ast::Attribute>,
244244

245-
// Is it an `unsafe fn`?
246-
pub is_unsafe: bool,
247-
248245
/// Can we combine fieldless variants for enums into a single match arm?
249246
pub unify_fieldless_variants: bool,
250247

251248
pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
249+
250+
/// Is it an `unsafe fn`?
251+
pub is_unsafe: bool,
252252
}
253253

254254
/// All the data about the data structure/method being derived upon.
@@ -451,23 +451,27 @@ impl<'a> TraitDef<'a> {
451451
};
452452
// Keep the lint attributes of the previous item to control how the
453453
// generated implementations are linted
454-
let mut attrs = newitem.attrs.clone();
455-
attrs.extend(
456-
item.attrs
457-
.iter()
458-
.filter(|a| {
459-
[
460-
sym::allow,
461-
sym::warn,
462-
sym::deny,
463-
sym::forbid,
464-
sym::stable,
465-
sym::unstable,
466-
]
467-
.contains(&a.name_or_empty())
468-
})
469-
.cloned(),
470-
);
454+
let attrs = newitem
455+
.attrs
456+
.iter()
457+
.cloned()
458+
.chain(
459+
item.attrs
460+
.iter()
461+
.filter(|a| {
462+
[
463+
sym::allow,
464+
sym::warn,
465+
sym::deny,
466+
sym::forbid,
467+
sym::stable,
468+
sym::unstable,
469+
]
470+
.contains(&a.name_or_empty())
471+
})
472+
.cloned(),
473+
)
474+
.collect();
471475
push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
472476
}
473477
_ => unreachable!(),
@@ -542,7 +546,7 @@ impl<'a> TraitDef<'a> {
542546

543547
// Create the generic parameters
544548
params.extend(generics.params.iter().map(|param| match param.kind {
545-
GenericParamKind::Lifetime { .. } => param.clone(),
549+
GenericParamKind::Lifetime { .. } | GenericParamKind::Const { .. } => param.clone(),
546550
GenericParamKind::Type { .. } => {
547551
// I don't think this can be moved out of the loop, since
548552
// a GenericBound requires an ast id
@@ -561,7 +565,6 @@ impl<'a> TraitDef<'a> {
561565

562566
cx.typaram(self.span, param.ident, vec![], bounds, None)
563567
}
564-
GenericParamKind::Const { .. } => param.clone(),
565568
}));
566569

567570
// and similarly for where clauses
@@ -605,38 +608,37 @@ impl<'a> TraitDef<'a> {
605608
let ty_param_names: Vec<Symbol> =
606609
ty_params.map(|ty_param| ty_param.ident.name).collect();
607610

608-
for field_ty in field_tys {
611+
let bounds: Vec<_> = self
612+
.additional_bounds
613+
.iter()
614+
.map(|p| cx.trait_bound(p.to_path(cx, self.span, type_ident, generics)))
615+
// require the current trait
616+
.chain(iter::once(cx.trait_bound(trait_path.clone())))
617+
.collect();
618+
let preds = field_tys.iter().flat_map(|field_ty| {
609619
let tys = find_type_parameters(&field_ty, &ty_param_names, cx);
610-
611-
for ty in tys {
620+
tys.into_iter().filter_map(|ty| {
612621
// if we have already handled this type, skip it
613622
if let ast::TyKind::Path(_, ref p) = ty.kind {
614623
if p.segments.len() == 1
615624
&& ty_param_names.contains(&p.segments[0].ident.name)
616625
{
617-
continue;
618-
};
626+
return None;
627+
}
619628
}
620-
let mut bounds: Vec<_> = self
621-
.additional_bounds
622-
.iter()
623-
.map(|p| cx.trait_bound(p.to_path(cx, self.span, type_ident, generics)))
624-
.collect();
625-
626-
// require the current trait
627-
bounds.push(cx.trait_bound(trait_path.clone()));
628629

629630
let predicate = ast::WhereBoundPredicate {
630631
span: self.span,
631632
bound_generic_params: Vec::new(),
632633
bounded_ty: ty,
633-
bounds,
634+
bounds: bounds.clone(),
634635
};
635636

636637
let predicate = ast::WherePredicate::BoundPredicate(predicate);
637-
where_clause.predicates.push(predicate);
638-
}
639-
}
638+
Some(predicate)
639+
})
640+
});
641+
where_clause.predicates.extend(preds);
640642
}
641643
}
642644

@@ -678,11 +680,14 @@ impl<'a> TraitDef<'a> {
678680
cx.attribute(list)
679681
};
680682

681-
let mut a = vec![attr, unused_qual];
682-
a.extend(self.attributes.iter().cloned());
683+
let a = iter::once(attr)
684+
.chain(iter::once(unused_qual))
685+
.chain(self.attributes.iter().cloned())
686+
.collect();
683687

684688
let unsafety = if self.is_unsafe { ast::Unsafe::Yes(self.span) } else { ast::Unsafe::No };
685-
689+
let mut items = methods;
690+
items.extend(associated_types);
686691
cx.item(
687692
self.span,
688693
Ident::invalid(),
@@ -695,7 +700,7 @@ impl<'a> TraitDef<'a> {
695700
generics: trait_generics,
696701
of_trait: opt_trait_ref,
697702
self_ty: self_type,
698-
items: methods.into_iter().chain(associated_types).collect(),
703+
items,
699704
},
700705
)
701706
}
@@ -709,9 +714,6 @@ impl<'a> TraitDef<'a> {
709714
from_scratch: bool,
710715
use_temporaries: bool,
711716
) -> P<ast::Item> {
712-
let field_tys: Vec<P<ast::Ty>> =
713-
struct_def.fields().iter().map(|field| field.ty.clone()).collect();
714-
715717
let methods = self
716718
.methods
717719
.iter()
@@ -744,6 +746,8 @@ impl<'a> TraitDef<'a> {
744746
})
745747
.collect();
746748

749+
let field_tys: Vec<P<ast::Ty>> =
750+
struct_def.fields().iter().map(|field| field.ty.clone()).collect();
747751
self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
748752
}
749753

@@ -755,11 +759,11 @@ impl<'a> TraitDef<'a> {
755759
generics: &Generics,
756760
from_scratch: bool,
757761
) -> P<ast::Item> {
758-
let mut field_tys = Vec::new();
759-
760-
for variant in &enum_def.variants {
761-
field_tys.extend(variant.data.fields().iter().map(|field| field.ty.clone()));
762-
}
762+
let field_tys = enum_def
763+
.variants
764+
.iter()
765+
.flat_map(|variant| variant.data.fields().iter().map(|field| field.ty.clone()))
766+
.collect();
763767

764768
let methods = self
765769
.methods
@@ -980,22 +984,22 @@ impl<'a> MethodDef<'a> {
980984
nonself_args: &[P<Expr>],
981985
use_temporaries: bool,
982986
) -> P<Expr> {
983-
let mut raw_fields = Vec::new(); // Vec<[fields of self],
984-
// [fields of next Self arg], [etc]>
985-
let mut patterns = Vec::new();
986-
for i in 0..self_args.len() {
987-
let struct_path = cx.path(trait_.span, vec![type_ident]);
988-
let (pat, ident_expr) = trait_.create_struct_pattern(
989-
cx,
990-
struct_path,
991-
struct_def,
992-
&format!("__self_{}", i),
993-
ast::Mutability::Not,
994-
use_temporaries,
995-
);
996-
patterns.push(pat);
997-
raw_fields.push(ident_expr);
998-
}
987+
// raw_fields: Vec<[fields of self],
988+
// patterns: [fields of next Self arg], [etc]>
989+
let (patterns, raw_fields): (Vec<_>, Vec<_>) = (0..self_args.len())
990+
.map(|i| {
991+
let struct_path = cx.path(trait_.span, vec![type_ident]);
992+
let (pat, ident_expr) = trait_.create_struct_pattern(
993+
cx,
994+
struct_path,
995+
struct_def,
996+
&format!("__self_{}", i),
997+
ast::Mutability::Not,
998+
use_temporaries,
999+
);
1000+
(pat, ident_expr)
1001+
})
1002+
.unzip();
9991003

10001004
// transpose raw_fields
10011005
let fields = if !raw_fields.is_empty() {
@@ -1555,18 +1559,21 @@ impl<'a> TraitDef<'a> {
15551559
mutbl: ast::Mutability,
15561560
use_temporaries: bool,
15571561
) -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
1558-
let mut paths = Vec::new();
1559-
let mut ident_exprs = Vec::new();
1560-
for (i, struct_field) in struct_def.fields().iter().enumerate() {
1561-
let sp = struct_field.span.with_ctxt(self.span.ctxt());
1562-
let ident = Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
1563-
paths.push(ident.with_span_pos(sp));
1564-
let val = cx.expr_path(cx.path_ident(sp, ident));
1565-
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
1566-
let val = cx.expr(sp, ast::ExprKind::Paren(val));
1567-
1568-
ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
1569-
}
1562+
let (paths, ident_exprs): (Vec<_>, Vec<_>) = struct_def
1563+
.fields()
1564+
.iter()
1565+
.enumerate()
1566+
.map(|(i, struct_field)| {
1567+
let sp = struct_field.span.with_ctxt(self.span.ctxt());
1568+
let ident = Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
1569+
1570+
let val = cx.expr_path(cx.path_ident(sp, ident));
1571+
let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
1572+
let val = cx.expr(sp, ast::ExprKind::Paren(val));
1573+
1574+
(ident.with_span_pos(sp), (sp, struct_field.ident, val, &struct_field.attrs[..]))
1575+
})
1576+
.unzip();
15701577

15711578
let subpats = self.create_subpatterns(cx, paths, mutbl, use_temporaries);
15721579
let pattern = match *struct_def {
@@ -1575,11 +1582,13 @@ impl<'a> TraitDef<'a> {
15751582
.into_iter()
15761583
.zip(&ident_exprs)
15771584
.map(|(pat, &(sp, ident, ..))| {
1578-
if ident.is_none() {
1579-
cx.span_bug(sp, "a braced struct with unnamed fields in `derive`");
1580-
}
1585+
let ident = if let Some(ident) = ident {
1586+
ident
1587+
} else {
1588+
cx.span_bug(sp, "a braced struct with unnamed fields in `derive`")
1589+
};
15811590
ast::FieldPat {
1582-
ident: ident.unwrap(),
1591+
ident: ident,
15831592
is_shorthand: false,
15841593
attrs: ast::AttrVec::new(),
15851594
id: ast::DUMMY_NODE_ID,

0 commit comments

Comments
 (0)