Skip to content

Commit dbf982c

Browse files
matthewjasperphilberty
authored andcommitted
gccrs: Parse statement macros as statements.
gcc/rust/ChangeLog: * ast/rust-ast.h (Expr::to_stmt): Remove method. * ast/rust-macro.h (MacroInvocation::to_stmt): Remove override. * ast/rust-stmt.h: Remove use of Expr::to_stmt. * expand/rust-macro-expand.h (struct MacroExpander): Add EXPR/STMT and remove BLOCK from ContextType. * expand/rust-expand-visitor.cc (ExpandVisitor::maybe_expand_expr): Use EXPR context. (ExpandVisitor::expand_inner_stmts): Use STMT context. (ExpandVisitor::visitor): Remove use of BLOCK context. * expand/rust-macro-expand.cc (transcribe_on_delimiter): Remove function. (transcribe_context): Use EXPR/STMT contexts. (MacroExpander::parse_proc_macro_output): Use EXPR/STMT contexts. * parse/rust-parse-impl.h (Parser::parse_stmt): Delegate macro parsing to parse_expr_stmt, check for ! after macro_rules. (Parser::parse_expr_stmt): Parse macro statements/expression statements starting with a macro. (Parser::parse_match_expr): Don't modify flag unnecessarily. (Parser::parse_stmt_or_expr): Parse macro statements/expression statements starting with a macro. (Parser::parse_path_based_stmt_or_expr): Remove method. (Parser::parse_macro_invocation_maybe_semi): Remove method. (Parser::parse_expr): Move code into left_denotations. (Parser::left_denotations): New method. (Parser::null_denotation): Split out methods for cases with and without paths. (Parser::null_denotation_path): New method. (Parser::null_denotation_not_path): New method. (Parser::parse_macro_invocation_partial): Don't check for semicolon here. * parse/rust-parse.h: Update declarations. gcc/testsuite/ChangeLog: * rust/compile/braced_macro_arm.rs: New test. * rust/compile/braced_macro_statements1.rs: New test. * rust/compile/braced_macro_statements2.rs: New test. * rust/compile/braced_macro_statements3.rs: New test. * rust/compile/issue-2225.rs: Update test. Signed-off-by: Matthew Jasper <[email protected]>
1 parent 33544f7 commit dbf982c

13 files changed

+353
-622
lines changed

gcc/rust/ast/rust-ast.h

-2
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,6 @@ class Expr : public Node
988988

989989
virtual std::vector<Attribute> &get_outer_attrs () = 0;
990990

991-
virtual Expr *to_stmt () const { return clone_expr_impl (); }
992-
993991
// TODO: think of less hacky way to implement this kind of thing
994992
// Sets outer attributes.
995993
virtual void set_outer_attrs (std::vector<Attribute>) = 0;

gcc/rust/ast/rust-macro.h

-9
Original file line numberDiff line numberDiff line change
@@ -811,15 +811,6 @@ class MacroInvocation : public TypeNoBounds,
811811
{
812812
return clone_macro_invocation_impl ();
813813
}
814-
815-
Expr *to_stmt () const override
816-
817-
{
818-
auto new_impl = clone_macro_invocation_impl ();
819-
new_impl->is_semi_coloned = true;
820-
821-
return new_impl;
822-
}
823814
};
824815

825816
// more generic meta item path-only form

gcc/rust/ast/rust-stmt.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ class ExprStmt : public Stmt
201201

202202
std::vector<LetStmt *> locals;
203203

204-
ExprStmt (std::unique_ptr<Expr> expr, Location locus, bool semicolon_followed)
205-
: expr (expr->to_stmt ()), locus (locus),
204+
ExprStmt (std::unique_ptr<Expr> &&expr, Location locus,
205+
bool semicolon_followed)
206+
: expr (std::move (expr)), locus (locus),
206207
semicolon_followed (semicolon_followed)
207208
{}
208209

gcc/rust/expand/rust-expand-visitor.cc

+4-9
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ void
232232
ExpandVisitor::expand_inner_stmts (
233233
std::vector<std::unique_ptr<AST::Stmt>> &stmts)
234234
{
235-
expander.push_context (MacroExpander::ContextType::BLOCK);
235+
expander.push_context (MacroExpander::ContextType::STMT);
236236

237237
for (auto it = stmts.begin (); it != stmts.end (); it++)
238238
{
@@ -272,10 +272,9 @@ ExpandVisitor::expand_inner_stmts (
272272
void
273273
ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
274274
{
275-
// FIXME: ARTHUR: Why isn't there a ContextType::EXPR? We can only
276-
// reach `parse_expr` once in MacroExpander::transcribe_rule(), but it
277-
// would make things clearer wouldn't it?
275+
expander.push_context (MacroExpander::ContextType::EXPR);
278276
expr->accept_vis (*this);
277+
expander.pop_context ();
279278

280279
auto final_fragment = expander.take_expanded_fragment ();
281280
if (final_fragment.should_expand ()
@@ -732,12 +731,8 @@ ExpandVisitor::visit (AST::BlockExpr &expr)
732731
{
733732
expand_inner_stmts (expr.get_statements ());
734733

735-
expander.push_context (MacroExpander::ContextType::BLOCK);
736-
737734
if (expr.has_tail_expr ())
738735
maybe_expand_expr (expr.get_tail_expr ());
739-
740-
expander.pop_context ();
741736
}
742737

743738
void
@@ -1438,7 +1433,7 @@ ExpandVisitor::visit (AST::LetStmt &stmt)
14381433
void
14391434
ExpandVisitor::visit (AST::ExprStmt &stmt)
14401435
{
1441-
visit (stmt.get_expr ());
1436+
maybe_expand_expr (stmt.get_expr ());
14421437
}
14431438

14441439
void

gcc/rust/expand/rust-macro-expand.cc

+7-13
Original file line numberDiff line numberDiff line change
@@ -894,16 +894,6 @@ transcribe_type (Parser<MacroInvocLexer> &parser)
894894
return AST::Fragment ({std::move (type)}, lexer.get_token_slice (start, end));
895895
}
896896

897-
static AST::Fragment
898-
transcribe_on_delimiter (Parser<MacroInvocLexer> &parser, bool semicolon,
899-
AST::DelimType delimiter, TokenId last_token_id)
900-
{
901-
if (semicolon || delimiter == AST::DelimType::CURLY)
902-
return transcribe_many_stmts (parser, last_token_id);
903-
else
904-
return transcribe_expression (parser);
905-
} // namespace Rust
906-
907897
static AST::Fragment
908898
transcribe_context (MacroExpander::ContextType ctx,
909899
Parser<MacroInvocLexer> &parser, bool semicolon,
@@ -945,9 +935,12 @@ transcribe_context (MacroExpander::ContextType ctx,
945935
case MacroExpander::ContextType::TYPE:
946936
return transcribe_type (parser);
947937
break;
938+
case MacroExpander::ContextType::STMT:
939+
return transcribe_many_stmts (parser, last_token_id, semicolon);
940+
case MacroExpander::ContextType::EXPR:
941+
return transcribe_expression (parser);
948942
default:
949-
return transcribe_on_delimiter (parser, semicolon, delimiter,
950-
last_token_id);
943+
gcc_unreachable ();
951944
}
952945
}
953946

@@ -1111,7 +1104,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
11111104
nodes.push_back ({std::move (result)});
11121105
}
11131106
break;
1114-
case ContextType::BLOCK:
1107+
case ContextType::STMT:
11151108
while (lex.peek_token ()->get_id () != END_OF_FILE)
11161109
{
11171110
auto result = parser.parse_stmt ();
@@ -1125,6 +1118,7 @@ MacroExpander::parse_proc_macro_output (ProcMacro::TokenStream ts)
11251118
case ContextType::TRAIT_IMPL:
11261119
case ContextType::EXTERN:
11271120
case ContextType::TYPE:
1121+
case ContextType::EXPR:
11281122
default:
11291123
gcc_unreachable ();
11301124
}

gcc/rust/expand/rust-macro-expand.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ struct MacroExpander
221221
enum class ContextType
222222
{
223223
ITEM,
224-
BLOCK,
224+
STMT,
225+
EXPR,
225226
EXTERN,
226227
TYPE,
227228
TRAIT,

0 commit comments

Comments
 (0)