From: Arthur Cohen <arthur.cohen@embecosm.com>
To: gcc-patches@gcc.gnu.org
Cc: gcc-rust@gcc.gnu.org, Arthur Cohen <arthur.cohen@embecosm.com>
Subject: [COMMITTED] gccrs: ast: Only expand expressions and types if the kind is right
Date: Tue, 31 Jan 2023 14:25:04 +0100 [thread overview]
Message-ID: <20230131132504.661840-1-arthur.cohen@embecosm.com> (raw)
gcc/rust/ChangeLog:
* ast/rust-ast.h: Add assertions and accessors for fragment nodes.
* expand/rust-attribute-visitor.cc (AttrVisitor::visit): Fix expansion
context typo when visiting `InherentImpl` items.
(AttrVisitor::maybe_expand_expr): Use new Fragment accessor to fetch
properly typed node.
(AttrVisitor::maybe_expand_type): Likewise.
* expand/rust-macro-expand.cc (transcribe_type): Emit parse errors
when trying to parse a type.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/rust/ast/rust-ast.h | 15 +++++++++++++++
gcc/rust/expand/rust-attribute-visitor.cc | 11 +++++++----
gcc/rust/expand/rust-macro-expand.cc | 4 +++-
3 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 213208efb56..58fe2674479 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -24,6 +24,7 @@
#include "rust-hir-map.h"
#include "rust-token.h"
#include "rust-location.h"
+#include "rust-diagnostics.h"
namespace Rust {
// TODO: remove typedefs and make actual types for these
@@ -1868,6 +1869,10 @@ private:
*/
bool is_single_fragment () const { return nodes.size () == 1; }
+ bool is_single_fragment (SingleASTNode::NodeType expected) const
+ {
+ return is_single_fragment () && nodes[0].get_kind () == expected;
+ }
bool is_single_fragment_kind (SingleASTNode::NodeType kind) const
{
@@ -1913,6 +1918,16 @@ public:
bool should_expand () const { return !is_error (); }
+ bool is_expression_fragment () const
+ {
+ return is_single_fragment (SingleASTNode::NodeType::EXPRESSION);
+ }
+
+ bool is_type_fragment () const
+ {
+ return is_single_fragment (SingleASTNode::NodeType::TYPE);
+ }
+
std::unique_ptr<Expr> take_expression_fragment ()
{
rust_assert (is_single_fragment_kind (SingleASTNode::NodeType::EXPRESSION));
diff --git a/gcc/rust/expand/rust-attribute-visitor.cc b/gcc/rust/expand/rust-attribute-visitor.cc
index 15aedbfa668..673f0432a30 100644
--- a/gcc/rust/expand/rust-attribute-visitor.cc
+++ b/gcc/rust/expand/rust-attribute-visitor.cc
@@ -2662,7 +2662,7 @@ AttrVisitor::visit (AST::InherentImpl &impl)
for (auto ¶m : impl.get_generic_params ())
param->accept_vis (*this);
- expander.push_context (MacroExpander::ContextType::TYPE);
+ expander.push_context (MacroExpander::ContextType::ITEM);
auto &type = impl.get_type ();
type->accept_vis (*this);
@@ -2706,7 +2706,7 @@ AttrVisitor::visit (AST::TraitImpl &impl)
for (auto ¶m : impl.get_generic_params ())
param->accept_vis (*this);
- expander.push_context (MacroExpander::ContextType::TYPE);
+ expander.push_context (MacroExpander::ContextType::ITEM);
auto &type = impl.get_type ();
type->accept_vis (*this);
@@ -3427,11 +3427,13 @@ AttrVisitor::visit (AST::BareFunctionType &type)
// no where clause, apparently
}
+
void
AttrVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
{
auto final_fragment = expand_macro_fragment_recursive ();
- if (final_fragment.should_expand ())
+ if (final_fragment.should_expand ()
+ && final_fragment.is_expression_fragment ())
expr = final_fragment.take_expression_fragment ();
}
@@ -3439,7 +3441,8 @@ void
AttrVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
{
auto final_fragment = expand_macro_fragment_recursive ();
- if (final_fragment.should_expand ())
+ if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
type = final_fragment.take_type_fragment ();
}
+
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index ed1b838c987..c68faba86ad 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -864,7 +864,9 @@ transcribe_expression (Parser<MacroInvocLexer> &parser)
static AST::ASTFragment
transcribe_type (Parser<MacroInvocLexer> &parser)
{
- auto type = parser.parse_type ();
+ auto type = parser.parse_type (true);
+ for (auto err : parser.get_errors ())
+ err.emit_error ();
return AST::ASTFragment ({std::move (type)});
}
--
2.39.1
reply other threads:[~2023-01-31 13:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230131132504.661840-1-arthur.cohen@embecosm.com \
--to=arthur.cohen@embecosm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=gcc-rust@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).