Skip to content

Commit 4277c84

Browse files
committed
Add assert macro handler
Assert macro handler was missing, insert a basic handler that desugars to a condition and a call to panic. gcc/rust/ChangeLog: * expand/rust-macro-builtins-log-debug.cc (MacroBuiltin::assert_handler): Add basic assert builtin macro handler. gcc/testsuite/ChangeLog: * rust/compile/assert_missing_panic.rs: New test. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
1 parent 5c4de7f commit 4277c84

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

gcc/rust/expand/rust-macro-builtins-log-debug.cc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include "rust-ast-fragment.h"
2020
#include "rust-macro-builtins.h"
2121
#include "rust-macro-builtins-helpers.h"
22+
#include "rust-ast-builder.h"
23+
#include "optional.h"
24+
#include "rust-ast-collector.h"
2225

2326
namespace Rust {
2427
tl::optional<AST::Fragment>
@@ -27,6 +30,75 @@ MacroBuiltin::assert_handler (location_t invoc_locus,
2730
AST::InvocKind semicolon)
2831
{
2932
rust_debug ("assert!() called");
33+
auto tt = invoc.get_delim_tok_tree ();
34+
MacroInvocLexer lex (tt.to_token_stream ());
35+
Parser<MacroInvocLexer> parser (lex);
36+
37+
auto last_token_id = macro_end_token (tt, parser);
38+
bool has_error = false;
39+
40+
auto expanded_expr = try_expand_many_expr (parser, last_token_id,
41+
invoc.get_expander (), has_error);
42+
if (expanded_expr.size () < 1)
43+
{
44+
rust_error_at (invoc_locus,
45+
"macro requires a boolean expression as an argument");
46+
return AST::Fragment::create_error ();
47+
}
48+
auto expr_to_assert = std::move (expanded_expr[0]);
49+
expanded_expr.erase (expanded_expr.begin ());
50+
51+
if (expanded_expr.size () > 1)
52+
{
53+
rust_sorry_at (
54+
invoc_locus,
55+
"The second form of assert with a message is not supported yet");
56+
57+
return AST::Fragment::create_error ();
58+
}
59+
60+
auto pending_invocations = check_for_eager_invocations (expanded_expr);
61+
if (!pending_invocations.empty ())
62+
return make_eager_builtin_invocation (BuiltinMacro::Assert, invoc_locus,
63+
invoc.get_delim_tok_tree (),
64+
std::move (pending_invocations));
65+
66+
AST::Builder b (invoc_locus);
67+
68+
std::vector<std::unique_ptr<AST::TokenTree>> panic_tree;
69+
const_TokenPtr open = Token::make (TokenId::LEFT_PAREN, invoc_locus);
70+
panic_tree.push_back (std::make_unique<AST::Token> (std::move (open)));
71+
72+
const_TokenPtr close = Token::make (TokenId::RIGHT_PAREN, invoc_locus);
73+
panic_tree.push_back (std::make_unique<AST::Token> (std::move (close)));
74+
75+
auto panic = AST::MacroInvocation::Regular (
76+
AST::MacroInvocData (AST::SimplePath (Identifier ("panic")),
77+
AST::DelimTokenTree (AST::DelimType::PARENS,
78+
std::move (panic_tree),
79+
invoc_locus)),
80+
{} /* outer attributes */, invoc_locus, true /* semicoloned */);
81+
auto stmt = b.statementify (std::move (panic));
82+
std::vector<std::unique_ptr<AST::Stmt>> stmts;
83+
stmts.push_back (std::move (stmt));
84+
auto block = b.block (std::move (stmts));
85+
auto negated_condition = std::unique_ptr<AST::NegationExpr> (
86+
new AST::NegationExpr (std::move (expr_to_assert),
87+
AST::NegationExpr::ExprType::NOT, {}, invoc_locus));
88+
89+
auto if_expr = std::make_unique<AST::IfExpr> (
90+
std::move (negated_condition) /* condition*/, std::move (block),
91+
std::vector<AST::Attribute>{}, invoc_locus);
92+
93+
auto node = AST::SingleASTNode (std::move (if_expr));
94+
95+
AST::TokenCollector collector;
96+
collector.visit (node);
97+
std::vector<std::unique_ptr<AST::Token>> tokens;
98+
for (auto &&token : collector.collect_tokens ())
99+
tokens.push_back (std::make_unique<AST::Token> (token));
100+
101+
return AST::Fragment ({node}, std::move (tokens));
30102

31103
return AST::Fragment::create_error ();
32104
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(rustc_attrs)]
2+
#![feature(no_core)]
3+
#![no_core]
4+
5+
#[macro_export]
6+
#[rustc_builtin_macro]
7+
macro_rules! assert {
8+
($($arg:tt)*) => {};
9+
}
10+
11+
const _: () = assert!(true);
12+
// { dg-error "could not resolve macro invocation .panic." "" { target *-*-* } .-1 }

0 commit comments

Comments
 (0)