Skip to content

Commit 858913b

Browse files
committed
mbe: Add fragment type adt to parse an ADT (struct, enum, or union)
1 parent ebb4389 commit 858913b

21 files changed

+219
-18
lines changed

compiler/rustc_ast/src/token.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,7 @@ pub enum NonterminalKind {
11021102
Vis,
11031103
TT,
11041104
Fn,
1105+
Adt,
11051106
}
11061107

11071108
impl NonterminalKind {
@@ -1140,6 +1141,7 @@ impl NonterminalKind {
11401141
sym::vis => NonterminalKind::Vis,
11411142
sym::tt => NonterminalKind::TT,
11421143
kw::Fn => NonterminalKind::Fn,
1144+
sym::adt => NonterminalKind::Adt,
11431145
_ => return None,
11441146
})
11451147
}
@@ -1162,6 +1164,7 @@ impl NonterminalKind {
11621164
NonterminalKind::Vis => sym::vis,
11631165
NonterminalKind::TT => sym::tt,
11641166
NonterminalKind::Fn => kw::Fn,
1167+
NonterminalKind::Adt => sym::adt,
11651168
}
11661169
}
11671170
}

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
15501550
IsInFollow::Yes
15511551
} else {
15521552
match kind {
1553-
NonterminalKind::Item | NonterminalKind::Fn => {
1553+
NonterminalKind::Item | NonterminalKind::Fn | NonterminalKind::Adt => {
15541554
// since items *must* be followed by either a `;` or a `}`, we can
15551555
// accept anything after them
15561556
IsInFollow::Yes

compiler/rustc_expand/src/mbe/quoted.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetiti
1414

1515
pub(crate) const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
1616
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, \
17-
`meta`, `tt`, `item`, `fn`, and `vis`, along with `expr_2021` and `pat_param` for edition compatibility";
17+
`meta`, `tt`, `item`, `fn`, 'adt', and `vis`, \
18+
along with `expr_2021` and `pat_param` for edition compatibility";
1819

1920
/// Which part of a macro rule we're parsing
2021
#[derive(Copy, Clone)]
@@ -142,7 +143,9 @@ fn parse(
142143
});
143144
NonterminalKind::TT
144145
});
145-
if matches!(kind, NonterminalKind::Fn) && !features.macro_fragments_more() {
146+
if matches!(kind, NonterminalKind::Fn | NonterminalKind::Adt)
147+
&& !features.macro_fragments_more()
148+
{
146149
let msg = "macro `:fn` and `:adt` fragments are unstable";
147150
feature_err(sess, sym::macro_fragments_more, span, msg).emit();
148151
}

compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ fn transcribe_pnr<'tx>(
437437
let kind = token::NtLifetime(*ident, *is_raw);
438438
TokenTree::token_alone(kind, sp)
439439
}
440-
ParseNtResult::Item(item) | ParseNtResult::Fn(item) => {
440+
ParseNtResult::Item(item) | ParseNtResult::Fn(item) | ParseNtResult::Adt(item) => {
441441
mk_delimited(item.span, MetaVarKind::Item, TokenStream::from_ast(item))
442442
}
443443
ParseNtResult::Block(block) => {

compiler/rustc_parse/messages.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ parse_no_digits_literal = no valid digits found for number
721721
parse_non_string_abi_literal = non-string ABI literal
722722
.suggestion = specify the ABI with a string literal
723723
724+
parse_nonterminal_expected_adt = expected a struct, enum, or union
724725
parse_nonterminal_expected_fn = expected a function
725726
parse_nonterminal_expected_ident = expected ident, found `{$token}`
726727
parse_nonterminal_expected_item_keyword = expected an item keyword

compiler/rustc_parse/src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2171,6 +2171,8 @@ pub(crate) enum UnexpectedNonterminal {
21712171
Statement(#[primary_span] Span),
21722172
#[diag(parse_nonterminal_expected_fn)]
21732173
Fn(#[primary_span] Span),
2174+
#[diag(parse_nonterminal_expected_adt)]
2175+
Adt(#[primary_span] Span),
21742176
#[diag(parse_nonterminal_expected_ident)]
21752177
Ident {
21762178
#[primary_span]

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,7 @@ pub enum ParseNtResult {
16701670
Lifetime(Ident, IdentIsRaw),
16711671
Item(Box<ast::Item>),
16721672
Fn(Box<ast::Item>),
1673+
Adt(Box<ast::Item>),
16731674
Block(Box<ast::Block>),
16741675
Stmt(Box<ast::Stmt>),
16751676
Pat(Box<ast::Pat>, NtPatKind),

compiler/rustc_parse/src/parser/nonterminal.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ impl<'a> Parser<'a> {
105105
NonterminalKind::TT
106106
| NonterminalKind::Item
107107
| NonterminalKind::Stmt
108-
| NonterminalKind::Fn => token.kind.close_delim().is_none(),
108+
| NonterminalKind::Fn
109+
| NonterminalKind::Adt => token.kind.close_delim().is_none(),
109110
}
110111
}
111112

@@ -133,6 +134,18 @@ impl<'a> Parser<'a> {
133134
Err(self.dcx().create_err(UnexpectedNonterminal::Fn(self.token.span)))
134135
}
135136
}
137+
NonterminalKind::Adt => {
138+
if let Some(item) = self.parse_item(ForceCollect::Yes)?
139+
&& matches!(
140+
item.kind,
141+
ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..)
142+
)
143+
{
144+
Ok(ParseNtResult::Adt(item))
145+
} else {
146+
Err(self.dcx().create_err(UnexpectedNonterminal::Adt(self.token.span)))
147+
}
148+
}
136149
NonterminalKind::Block => {
137150
// While a block *expression* may have attributes (e.g. `#[my_attr] { ... }`),
138151
// the ':block' matcher does not support them

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ symbols! {
422422
add_assign,
423423
add_with_overflow,
424424
address,
425+
adt,
425426
adt_const_params,
426427
advanced_slice_patterns,
427428
adx_target_feature,

tests/ui/feature-gates/feature-gate-macro-fragments-more.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22

33
macro_rules! use_fn { ($f:fn) => {} }
44
//~^ ERROR macro `:fn` and `:adt` fragments are unstable
5+
6+
macro_rules! use_adt { ($f:adt) => {} }
7+
//~^ ERROR macro `:fn` and `:adt` fragments are unstable

0 commit comments

Comments
 (0)