Skip to content

Commit c07d37b

Browse files
authored
Rollup merge of rust-lang#64035 - petrochenkov:stabmacgen, r=eddyb
Stabilize proc macros generating `macro_rules` items Fn-like and attribute proc macros can now generate `macro_rules` items. cc rust-lang#54727
2 parents e369d87 + d80be3b commit c07d37b

File tree

11 files changed

+84
-157
lines changed

11 files changed

+84
-157
lines changed

src/librustc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#![feature(test)]
5757
#![feature(in_band_lifetimes)]
5858
#![feature(crate_visibility_modifier)]
59-
#![feature(proc_macro_hygiene)]
59+
#![cfg_attr(bootstrap, feature(proc_macro_hygiene))]
6060
#![feature(log_syntax)]
6161
#![feature(associated_type_bounds)]
6262
#![feature(rustc_attrs)]

src/libsyntax/ext/expand.rs

+4-45
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ use crate::ext::mbe::macro_rules::annotate_err_with_kind;
1010
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
1111
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
1212
use crate::mut_visit::*;
13-
use crate::parse::{DirectoryOwnership, PResult, ParseSess};
13+
use crate::parse::{DirectoryOwnership, PResult};
1414
use crate::parse::token;
1515
use crate::parse::parser::Parser;
1616
use crate::print::pprust;
1717
use crate::ptr::P;
1818
use crate::symbol::{sym, Symbol};
1919
use crate::tokenstream::{TokenStream, TokenTree};
20-
use crate::visit::{self, Visitor};
20+
use crate::visit::Visitor;
2121
use crate::util::map_in_place::MapInPlace;
2222

2323
use errors::{Applicability, FatalError};
@@ -577,10 +577,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
577577
SyntaxExtensionKind::Bang(expander) => {
578578
self.gate_proc_macro_expansion_kind(span, fragment_kind);
579579
let tok_result = expander.expand(self.cx, span, mac.stream());
580-
let result =
581-
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span);
582-
self.gate_proc_macro_expansion(span, &result);
583-
result
580+
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
584581
}
585582
SyntaxExtensionKind::LegacyBang(expander) => {
586583
let prev = self.cx.current_expansion.prior_type_ascription;
@@ -624,10 +621,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
624621
})), DUMMY_SP).into();
625622
let input = self.extract_proc_macro_attr_input(attr.item.tokens, span);
626623
let tok_result = expander.expand(self.cx, span, input, item_tok);
627-
let res =
628-
self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span);
629-
self.gate_proc_macro_expansion(span, &res);
630-
res
624+
self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span)
631625
}
632626
SyntaxExtensionKind::LegacyAttr(expander) => {
633627
match attr.parse_meta(self.cx.parse_sess) {
@@ -718,41 +712,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
718712
);
719713
}
720714

721-
fn gate_proc_macro_expansion(&self, span: Span, fragment: &AstFragment) {
722-
if self.cx.ecfg.proc_macro_hygiene() {
723-
return
724-
}
725-
726-
fragment.visit_with(&mut DisallowMacros {
727-
span,
728-
parse_sess: self.cx.parse_sess,
729-
});
730-
731-
struct DisallowMacros<'a> {
732-
span: Span,
733-
parse_sess: &'a ParseSess,
734-
}
735-
736-
impl<'ast, 'a> Visitor<'ast> for DisallowMacros<'a> {
737-
fn visit_item(&mut self, i: &'ast ast::Item) {
738-
if let ast::ItemKind::MacroDef(_) = i.kind {
739-
emit_feature_err(
740-
self.parse_sess,
741-
sym::proc_macro_hygiene,
742-
self.span,
743-
GateIssue::Language,
744-
"procedural macros cannot expand to macro definitions",
745-
);
746-
}
747-
visit::walk_item(self, i);
748-
}
749-
750-
fn visit_mac(&mut self, _mac: &'ast ast::Mac) {
751-
// ...
752-
}
753-
}
754-
}
755-
756715
fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
757716
let kind = match kind {
758717
AstFragmentKind::Expr |

src/libsyntax_pos/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#![feature(non_exhaustive)]
1313
#![feature(optin_builtin_traits)]
1414
#![feature(rustc_attrs)]
15-
#![feature(proc_macro_hygiene)]
15+
#![cfg_attr(bootstrap, feature(proc_macro_hygiene))]
1616
#![feature(specialization)]
1717
#![feature(step_trait)]
1818

src/test/ui/macros/same-sequence-span.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// left-hand side of a macro definition behave as if they had unique spans, and in particular that
55
// they don't crash the compiler.
66

7-
#![feature(proc_macro_hygiene)]
87
#![allow(unused_macros)]
98

109
extern crate proc_macro_sequence;

src/test/ui/macros/same-sequence-span.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
2-
--> $DIR/same-sequence-span.rs:15:18
2+
--> $DIR/same-sequence-span.rs:14:18
33
|
44
LL | (1 $x:expr $($y:tt,)*
55
| ^^^^^ not allowed after `expr` fragments
66
|
77
= note: allowed there are: `=>`, `,` or `;`
88

99
error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
10-
--> $DIR/same-sequence-span.rs:16:18
10+
--> $DIR/same-sequence-span.rs:15:18
1111
|
1212
LL | $(= $z:tt)*
1313
| ^ not allowed after `expr` fragments
1414
|
1515
= note: allowed there are: `=>`, `,` or `;`
1616

1717
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
18-
--> $DIR/same-sequence-span.rs:20:1
18+
--> $DIR/same-sequence-span.rs:19:1
1919
|
2020
LL | proc_macro_sequence::make_foo!();
2121
| ^--------------------------------
@@ -30,7 +30,7 @@ LL | | fn main() {}
3030
= note: allowed there are: `=>`, `,` or `;`
3131

3232
error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
33-
--> $DIR/same-sequence-span.rs:20:1
33+
--> $DIR/same-sequence-span.rs:19:1
3434
|
3535
LL | proc_macro_sequence::make_foo!();
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
use proc_macro::*;
8+
9+
#[proc_macro]
10+
pub fn gen_macro_rules(_: TokenStream) -> TokenStream {
11+
"
12+
macro_rules! generated {() => {
13+
struct ItemDef;
14+
let local_def = 0;
15+
16+
ItemUse; // OK
17+
local_use; // ERROR
18+
break 'label_use; // ERROR
19+
20+
type DollarCrate = $crate::ItemUse; // OK
21+
}}
22+
".parse().unwrap()
23+
}

src/test/ui/proc-macro/auxiliary/more-gates.rs

-35
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// `macro_rules` items produced by transparent macros have correct hygiene in basic cases.
2+
// Local variables and labels are hygienic, items are not hygienic.
3+
// `$crate` refers to the crate that defines `macro_rules` and not the outer transparent macro.
4+
5+
// aux-build:gen-macro-rules-hygiene.rs
6+
7+
#[macro_use]
8+
extern crate gen_macro_rules_hygiene;
9+
10+
struct ItemUse;
11+
12+
gen_macro_rules!();
13+
//~^ ERROR use of undeclared label `'label_use`
14+
//~| ERROR cannot find value `local_use` in this scope
15+
16+
fn main() {
17+
'label_use: loop {
18+
let local_use = 1;
19+
generated!();
20+
ItemDef; // OK
21+
local_def; //~ ERROR cannot find value `local_def` in this scope
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0426]: use of undeclared label `'label_use`
2+
--> $DIR/gen-macro-rules-hygiene.rs:12:1
3+
|
4+
LL | gen_macro_rules!();
5+
| ^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use`
6+
...
7+
LL | generated!();
8+
| ------------- in this macro invocation
9+
10+
error[E0425]: cannot find value `local_use` in this scope
11+
--> $DIR/gen-macro-rules-hygiene.rs:12:1
12+
|
13+
LL | gen_macro_rules!();
14+
| ^^^^^^^^^^^^^^^^^^^ not found in this scope
15+
...
16+
LL | generated!();
17+
| ------------- in this macro invocation
18+
19+
error[E0425]: cannot find value `local_def` in this scope
20+
--> $DIR/gen-macro-rules-hygiene.rs:21:9
21+
|
22+
LL | local_def;
23+
| ^^^^^^^^^ not found in this scope
24+
25+
error: aborting due to 3 previous errors
26+
27+
Some errors have detailed explanations: E0425, E0426.
28+
For more information about an error, try `rustc --explain E0425`.

src/test/ui/proc-macro/more-gates.rs

-22
This file was deleted.

src/test/ui/proc-macro/more-gates.stderr

-48
This file was deleted.

0 commit comments

Comments
 (0)