Skip to content

Commit b003dd6

Browse files
committed
expand: Merge expand_{bang,attr,derive}_invoc into a single function
It's more convenient to have all this highly related stuff together on one screen (for future refactorings). The `expand_invoc` function is compact enough now, after all the previous refactorings.
1 parent 374a80a commit b003dd6

File tree

2 files changed

+79
-117
lines changed

2 files changed

+79
-117
lines changed

src/libsyntax/ext/expand.rs

Lines changed: 78 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
327327

328328
// FIXME(jseyfried): Refactor out the following logic
329329
let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
330-
let fragment = self.expand_invoc(invoc, &ext);
330+
let fragment = self.expand_invoc(invoc, &ext.kind);
331331
self.collect_invocations(fragment, &[])
332332
} else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind {
333333
if !item.derive_allowed() {
@@ -474,12 +474,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
474474
}
475475
}
476476

477-
fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtension) -> AstFragment {
478-
if invoc.fragment_kind == AstFragmentKind::ForeignItems &&
479-
!self.cx.ecfg.macros_in_extern() {
480-
if let SyntaxExtensionKind::NonMacroAttr { .. } = ext.kind {} else {
477+
fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstFragment {
478+
let (fragment_kind, span) = (invoc.fragment_kind, invoc.span());
479+
if fragment_kind == AstFragmentKind::ForeignItems && !self.cx.ecfg.macros_in_extern() {
480+
if let SyntaxExtensionKind::NonMacroAttr { .. } = ext {} else {
481481
emit_feature_err(&self.cx.parse_sess, sym::macros_in_extern,
482-
invoc.span(), GateIssue::Language,
482+
span, GateIssue::Language,
483483
"macro invocations in `extern {}` blocks are experimental");
484484
}
485485
}
@@ -499,58 +499,84 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
499499
}
500500

501501
match invoc.kind {
502-
InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext),
503-
InvocationKind::Attr { .. } => self.expand_attr_invoc(invoc, ext),
504-
InvocationKind::Derive { .. } => self.expand_derive_invoc(invoc, ext),
505-
}
506-
}
507-
508-
fn expand_attr_invoc(&mut self,
509-
invoc: Invocation,
510-
ext: &SyntaxExtension)
511-
-> AstFragment {
512-
let (attr, mut item) = match invoc.kind {
513-
InvocationKind::Attr { attr: Some(attr), item, .. } => (attr, item),
514-
_ => unreachable!(),
515-
};
516-
517-
match &ext.kind {
518-
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
519-
attr::mark_known(&attr);
520-
if *mark_used {
521-
attr::mark_used(&attr);
502+
InvocationKind::Bang { mac, .. } => match ext {
503+
SyntaxExtensionKind::Bang(expander) => {
504+
self.gate_proc_macro_expansion_kind(span, fragment_kind);
505+
let tok_result = expander.expand(self.cx, span, mac.node.stream());
506+
let result =
507+
self.parse_ast_fragment(tok_result, fragment_kind, &mac.node.path, span);
508+
self.gate_proc_macro_expansion(span, &result);
509+
result
510+
}
511+
SyntaxExtensionKind::LegacyBang(expander) => {
512+
let tok_result = expander.expand(self.cx, span, mac.node.stream());
513+
if let Some(result) = fragment_kind.make_from(tok_result) {
514+
result
515+
} else {
516+
let msg = format!("non-{kind} macro in {kind} position: {path}",
517+
kind = fragment_kind.name(), path = mac.node.path);
518+
self.cx.span_err(span, &msg);
519+
self.cx.trace_macros_diag();
520+
fragment_kind.dummy(span)
521+
}
522522
}
523-
item.visit_attrs(|attrs| attrs.push(attr));
524-
invoc.fragment_kind.expect_from_annotatables(iter::once(item))
523+
_ => unreachable!()
525524
}
526-
SyntaxExtensionKind::LegacyAttr(expander) => {
527-
match attr.parse_meta(self.cx.parse_sess) {
528-
Ok(meta) => {
529-
let item = expander.expand(self.cx, attr.span, &meta, item);
530-
invoc.fragment_kind.expect_from_annotatables(item)
525+
InvocationKind::Attr { attr: Some(attr), mut item, .. } => match ext {
526+
SyntaxExtensionKind::Attr(expander) => {
527+
self.gate_proc_macro_attr_item(span, &item);
528+
let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item {
529+
Annotatable::Item(item) => token::NtItem(item),
530+
Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()),
531+
Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()),
532+
Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()),
533+
Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
534+
Annotatable::Expr(expr) => token::NtExpr(expr),
535+
})), DUMMY_SP).into();
536+
let input = self.extract_proc_macro_attr_input(attr.tokens, span);
537+
let tok_result = expander.expand(self.cx, span, input, item_tok);
538+
let res = self.parse_ast_fragment(tok_result, fragment_kind, &attr.path, span);
539+
self.gate_proc_macro_expansion(span, &res);
540+
res
541+
}
542+
SyntaxExtensionKind::LegacyAttr(expander) => {
543+
match attr.parse_meta(self.cx.parse_sess) {
544+
Ok(meta) => {
545+
let item = expander.expand(self.cx, span, &meta, item);
546+
fragment_kind.expect_from_annotatables(item)
547+
}
548+
Err(mut err) => {
549+
err.emit();
550+
fragment_kind.dummy(span)
551+
}
531552
}
532-
Err(mut err) => {
533-
err.emit();
534-
invoc.fragment_kind.dummy(attr.span)
553+
}
554+
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
555+
attr::mark_known(&attr);
556+
if *mark_used {
557+
attr::mark_used(&attr);
535558
}
559+
item.visit_attrs(|attrs| attrs.push(attr));
560+
fragment_kind.expect_from_annotatables(iter::once(item))
536561
}
562+
_ => unreachable!()
537563
}
538-
SyntaxExtensionKind::Attr(expander) => {
539-
self.gate_proc_macro_attr_item(attr.span, &item);
540-
let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item {
541-
Annotatable::Item(item) => token::NtItem(item),
542-
Annotatable::TraitItem(item) => token::NtTraitItem(item.into_inner()),
543-
Annotatable::ImplItem(item) => token::NtImplItem(item.into_inner()),
544-
Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()),
545-
Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
546-
Annotatable::Expr(expr) => token::NtExpr(expr),
547-
})), DUMMY_SP).into();
548-
let input = self.extract_proc_macro_attr_input(attr.tokens, attr.span);
549-
let tok_result = expander.expand(self.cx, attr.span, input, item_tok);
550-
let res = self.parse_ast_fragment(tok_result, invoc.fragment_kind,
551-
&attr.path, attr.span);
552-
self.gate_proc_macro_expansion(attr.span, &res);
553-
res
564+
InvocationKind::Derive { path, item, item_with_markers } => match ext {
565+
SyntaxExtensionKind::Derive(expander) |
566+
SyntaxExtensionKind::LegacyDerive(expander) => {
567+
let (path, item) = match ext {
568+
SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers),
569+
_ => (path, item),
570+
};
571+
if !item.derive_allowed() {
572+
return fragment_kind.dummy(span);
573+
}
574+
let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path };
575+
let span = span.with_ctxt(self.cx.backtrace());
576+
let items = expander.expand(self.cx, span, &meta, item);
577+
fragment_kind.expect_from_annotatables(items)
578+
}
579+
_ => unreachable!()
554580
}
555581
_ => unreachable!()
556582
}
@@ -634,42 +660,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
634660
}
635661
}
636662

637-
/// Expand a macro invocation. Returns the resulting expanded AST fragment.
638-
fn expand_bang_invoc(&mut self,
639-
invoc: Invocation,
640-
ext: &SyntaxExtension)
641-
-> AstFragment {
642-
let kind = invoc.fragment_kind;
643-
let (mac, span) = match invoc.kind {
644-
InvocationKind::Bang { mac, span } => (mac, span),
645-
_ => unreachable!(),
646-
};
647-
let path = &mac.node.path;
648-
649-
match &ext.kind {
650-
SyntaxExtensionKind::Bang(expander) => {
651-
self.gate_proc_macro_expansion_kind(span, kind);
652-
let tok_result = expander.expand(self.cx, span, mac.node.stream());
653-
let result = self.parse_ast_fragment(tok_result, kind, path, span);
654-
self.gate_proc_macro_expansion(span, &result);
655-
result
656-
}
657-
SyntaxExtensionKind::LegacyBang(expander) => {
658-
let tok_result = expander.expand(self.cx, span, mac.node.stream());
659-
if let Some(result) = kind.make_from(tok_result) {
660-
result
661-
} else {
662-
let msg = format!("non-{kind} macro in {kind} position: {name}",
663-
name = path.segments[0].ident.name, kind = kind.name());
664-
self.cx.span_err(path.span, &msg);
665-
self.cx.trace_macros_diag();
666-
kind.dummy(span)
667-
}
668-
}
669-
_ => unreachable!()
670-
}
671-
}
672-
673663
fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
674664
let kind = match kind {
675665
AstFragmentKind::Expr => "expressions",
@@ -694,34 +684,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
694684
);
695685
}
696686

697-
/// Expand a derive invocation. Returns the resulting expanded AST fragment.
698-
fn expand_derive_invoc(&mut self,
699-
invoc: Invocation,
700-
ext: &SyntaxExtension)
701-
-> AstFragment {
702-
let (path, item) = match invoc.kind {
703-
InvocationKind::Derive { path, item, item_with_markers } => match ext.kind {
704-
SyntaxExtensionKind::LegacyDerive(..) => (path, item_with_markers),
705-
_ => (path, item),
706-
}
707-
_ => unreachable!(),
708-
};
709-
if !item.derive_allowed() {
710-
return invoc.fragment_kind.dummy(path.span);
711-
}
712-
713-
match &ext.kind {
714-
SyntaxExtensionKind::Derive(expander) |
715-
SyntaxExtensionKind::LegacyDerive(expander) => {
716-
let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span: path.span, path };
717-
let span = meta.span.with_ctxt(self.cx.backtrace());
718-
let items = expander.expand(self.cx, span, &meta, item);
719-
invoc.fragment_kind.expect_from_annotatables(items)
720-
}
721-
_ => unreachable!()
722-
}
723-
}
724-
725687
fn parse_ast_fragment(&mut self,
726688
toks: TokenStream,
727689
kind: AstFragmentKind,

src/test/ui/macros/macro-error.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error: non-type macro in type position: cfg
88
--> $DIR/macro-error.rs:8:12
99
|
1010
LL | let _: cfg!(foo) = ();
11-
| ^^^
11+
| ^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

0 commit comments

Comments
 (0)