Skip to content

Commit 737236f

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 679aad3 commit 737236f

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

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

Lines changed: 76 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,79 @@ 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+
if (expr_to_assert->get_expr_kind () != AST::Expr::Kind::MacroInvocation)
67+
{
68+
AST::Builder b (invoc_locus);
69+
70+
std::vector<std::unique_ptr<AST::TokenTree>> panic_tree;
71+
const_TokenPtr open = Token::make (TokenId::LEFT_PAREN, invoc_locus);
72+
panic_tree.push_back (std::make_unique<AST::Token> (std::move (open)));
73+
74+
const_TokenPtr close = Token::make (TokenId::RIGHT_PAREN, invoc_locus);
75+
panic_tree.push_back (std::make_unique<AST::Token> (std::move (close)));
76+
77+
auto panic = AST::MacroInvocation::Regular (
78+
AST::MacroInvocData (AST::SimplePath (Identifier ("panic")),
79+
AST::DelimTokenTree (AST::DelimType::PARENS,
80+
std::move (panic_tree),
81+
invoc_locus)),
82+
{} /* outer attributes */, invoc_locus, true /* semicoloned */);
83+
auto stmt = b.statementify (std::move (panic));
84+
std::vector<std::unique_ptr<AST::Stmt>> stmts;
85+
stmts.push_back (std::move (stmt));
86+
auto block = b.block (std::move (stmts));
87+
auto negated_condition = std::unique_ptr<AST::NegationExpr> (
88+
new AST::NegationExpr (std::move (expr_to_assert),
89+
AST::NegationExpr::ExprType::NOT, {},
90+
invoc_locus));
91+
92+
auto if_expr = std::make_unique<AST::IfExpr> (
93+
std::move (negated_condition) /* condition*/, std::move (block),
94+
std::vector<AST::Attribute>{}, invoc_locus);
95+
96+
auto node = AST::SingleASTNode (std::move (if_expr));
97+
98+
AST::TokenCollector collector;
99+
collector.visit (node);
100+
std::vector<std::unique_ptr<AST::Token>> tokens;
101+
for (auto &&token : collector.collect_tokens ())
102+
tokens.push_back (std::make_unique<AST::Token> (token));
103+
104+
return AST::Fragment ({node}, std::move (tokens));
105+
}
30106

31107
return AST::Fragment::create_error ();
32108
}
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)