Skip to content

Commit 8b9e138

Browse files
authored
Rollup merge of rust-lang#86491 - petrochenkov:derefact, r=Aaron1011
expand: Move some more derive logic to rustc_builtin_macros And cleanup some `unwrap`s in `cfg_eval`. Refactorings extracted from rust-lang#83354 and rust-lang#86057. r? ``@Aaron1011``
2 parents e5ecded + d9fd5ea commit 8b9e138

File tree

5 files changed

+37
-62
lines changed

5 files changed

+37
-62
lines changed

compiler/rustc_builtin_macros/src/cfg_eval.rs

+29-30
Original file line numberDiff line numberDiff line change
@@ -24,61 +24,60 @@ crate fn expand(
2424
annotatable: Annotatable,
2525
) -> Vec<Annotatable> {
2626
check_builtin_macro_attribute(ecx, meta_item, sym::cfg_eval);
27-
cfg_eval(ecx, annotatable)
27+
vec![cfg_eval(ecx, annotatable)]
2828
}
2929

30-
crate fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Vec<Annotatable> {
31-
let mut visitor = CfgEval {
30+
crate fn cfg_eval(ecx: &ExtCtxt<'_>, annotatable: Annotatable) -> Annotatable {
31+
CfgEval {
3232
cfg: &mut StripUnconfigured {
3333
sess: ecx.sess,
3434
features: ecx.ecfg.features,
3535
config_tokens: true,
3636
},
37-
};
38-
let annotatable = visitor.configure_annotatable(annotatable);
39-
vec![annotatable]
37+
}
38+
.configure_annotatable(annotatable)
39+
// Since the item itself has already been configured by the `InvocationCollector`,
40+
// we know that fold result vector will contain exactly one element.
41+
.unwrap()
4042
}
4143

4244
struct CfgEval<'a, 'b> {
4345
cfg: &'a mut StripUnconfigured<'b>,
4446
}
4547

46-
fn flat_map_annotatable(vis: &mut impl MutVisitor, annotatable: Annotatable) -> Annotatable {
47-
// Since the item itself has already been configured by the InvocationCollector,
48-
// we know that fold result vector will contain exactly one element
48+
fn flat_map_annotatable(
49+
vis: &mut impl MutVisitor,
50+
annotatable: Annotatable,
51+
) -> Option<Annotatable> {
4952
match annotatable {
50-
Annotatable::Item(item) => Annotatable::Item(vis.flat_map_item(item).pop().unwrap()),
53+
Annotatable::Item(item) => vis.flat_map_item(item).pop().map(Annotatable::Item),
5154
Annotatable::TraitItem(item) => {
52-
Annotatable::TraitItem(vis.flat_map_trait_item(item).pop().unwrap())
55+
vis.flat_map_trait_item(item).pop().map(Annotatable::TraitItem)
5356
}
5457
Annotatable::ImplItem(item) => {
55-
Annotatable::ImplItem(vis.flat_map_impl_item(item).pop().unwrap())
58+
vis.flat_map_impl_item(item).pop().map(Annotatable::ImplItem)
5659
}
5760
Annotatable::ForeignItem(item) => {
58-
Annotatable::ForeignItem(vis.flat_map_foreign_item(item).pop().unwrap())
61+
vis.flat_map_foreign_item(item).pop().map(Annotatable::ForeignItem)
5962
}
6063
Annotatable::Stmt(stmt) => {
61-
Annotatable::Stmt(stmt.map(|stmt| vis.flat_map_stmt(stmt).pop().unwrap()))
64+
vis.flat_map_stmt(stmt.into_inner()).pop().map(P).map(Annotatable::Stmt)
6265
}
63-
Annotatable::Expr(mut expr) => Annotatable::Expr({
66+
Annotatable::Expr(mut expr) => {
6467
vis.visit_expr(&mut expr);
65-
expr
66-
}),
67-
Annotatable::Arm(arm) => Annotatable::Arm(vis.flat_map_arm(arm).pop().unwrap()),
68-
Annotatable::ExprField(field) => {
69-
Annotatable::ExprField(vis.flat_map_expr_field(field).pop().unwrap())
68+
Some(Annotatable::Expr(expr))
7069
}
71-
Annotatable::PatField(fp) => {
72-
Annotatable::PatField(vis.flat_map_pat_field(fp).pop().unwrap())
70+
Annotatable::Arm(arm) => vis.flat_map_arm(arm).pop().map(Annotatable::Arm),
71+
Annotatable::ExprField(field) => {
72+
vis.flat_map_expr_field(field).pop().map(Annotatable::ExprField)
7373
}
74+
Annotatable::PatField(fp) => vis.flat_map_pat_field(fp).pop().map(Annotatable::PatField),
7475
Annotatable::GenericParam(param) => {
75-
Annotatable::GenericParam(vis.flat_map_generic_param(param).pop().unwrap())
76-
}
77-
Annotatable::Param(param) => Annotatable::Param(vis.flat_map_param(param).pop().unwrap()),
78-
Annotatable::FieldDef(sf) => {
79-
Annotatable::FieldDef(vis.flat_map_field_def(sf).pop().unwrap())
76+
vis.flat_map_generic_param(param).pop().map(Annotatable::GenericParam)
8077
}
81-
Annotatable::Variant(v) => Annotatable::Variant(vis.flat_map_variant(v).pop().unwrap()),
78+
Annotatable::Param(param) => vis.flat_map_param(param).pop().map(Annotatable::Param),
79+
Annotatable::FieldDef(sf) => vis.flat_map_field_def(sf).pop().map(Annotatable::FieldDef),
80+
Annotatable::Variant(v) => vis.flat_map_variant(v).pop().map(Annotatable::Variant),
8281
}
8382
}
8483

@@ -123,11 +122,11 @@ impl CfgEval<'_, '_> {
123122
self.cfg.configure(node)
124123
}
125124

126-
pub fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Annotatable {
125+
fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Annotatable> {
127126
// Tokenizing and re-parsing the `Annotatable` can have a significant
128127
// performance impact, so try to avoid it if possible
129128
if !CfgFinder::has_cfg_or_cfg_attr(&annotatable) {
130-
return annotatable;
129+
return Some(annotatable);
131130
}
132131

133132
// The majority of parsed attribute targets will never need to have early cfg-expansion

compiler/rustc_builtin_macros/src/derive.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ impl MultiItemModifier for Expander {
2626
return ExpandResult::Ready(vec![item]);
2727
}
2828

29+
let item = cfg_eval(ecx, item);
30+
2931
let result =
3032
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
3133
let template =
@@ -54,12 +56,12 @@ impl MultiItemModifier for Expander {
5456
report_path_args(sess, &meta);
5557
meta.path
5658
})
57-
.map(|path| (path, None))
59+
.map(|path| (path, item.clone(), None))
5860
.collect()
5961
});
6062

6163
match result {
62-
Ok(()) => ExpandResult::Ready(cfg_eval(ecx, item)),
64+
Ok(()) => ExpandResult::Ready(vec![item]),
6365
Err(Indeterminate) => ExpandResult::Retry(item),
6466
}
6567
}

compiler/rustc_expand/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ impl SyntaxExtension {
835835
/// Error type that denotes indeterminacy.
836836
pub struct Indeterminate;
837837

838-
pub type DeriveResolutions = Vec<(ast::Path, Option<Lrc<SyntaxExtension>>)>;
838+
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>)>;
839839

840840
pub trait ResolverExpand {
841841
fn next_node_id(&mut self) -> NodeId;

compiler/rustc_expand/src/expand.rs

+2-28
Original file line numberDiff line numberDiff line change
@@ -500,42 +500,16 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
500500
.resolver
501501
.take_derive_resolutions(expn_id)
502502
.map(|derives| {
503-
enum AnnotatableRef<'a> {
504-
Item(&'a P<ast::Item>),
505-
Stmt(&'a ast::Stmt),
506-
}
507-
let item = match &fragment {
508-
AstFragment::Items(items) => match &items[..] {
509-
[item] => AnnotatableRef::Item(item),
510-
_ => unreachable!(),
511-
},
512-
AstFragment::Stmts(stmts) => match &stmts[..] {
513-
[stmt] => AnnotatableRef::Stmt(stmt),
514-
_ => unreachable!(),
515-
},
516-
_ => unreachable!(),
517-
};
518-
519503
derive_invocations.reserve(derives.len());
520504
derives
521505
.into_iter()
522-
.map(|(path, _exts)| {
506+
.map(|(path, item, _exts)| {
523507
// FIXME: Consider using the derive resolutions (`_exts`)
524508
// instead of enqueuing the derives to be resolved again later.
525509
let expn_id = ExpnId::fresh(None);
526510
derive_invocations.push((
527511
Invocation {
528-
kind: InvocationKind::Derive {
529-
path,
530-
item: match item {
531-
AnnotatableRef::Item(item) => {
532-
Annotatable::Item(item.clone())
533-
}
534-
AnnotatableRef::Stmt(stmt) => {
535-
Annotatable::Stmt(P(stmt.clone()))
536-
}
537-
},
538-
},
512+
kind: InvocationKind::Derive { path, item },
539513
fragment_kind,
540514
expansion_data: ExpansionData {
541515
id: expn_id,

compiler/rustc_resolve/src/macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
380380
has_derive_copy: false,
381381
});
382382
let parent_scope = self.invocation_parent_scopes[&expn_id];
383-
for (i, (path, opt_ext)) in entry.resolutions.iter_mut().enumerate() {
383+
for (i, (path, _, opt_ext)) in entry.resolutions.iter_mut().enumerate() {
384384
if opt_ext.is_none() {
385385
*opt_ext = Some(
386386
match self.resolve_macro_path(

0 commit comments

Comments
 (0)