#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
*/
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
{
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));
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);
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);
// 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 ();
}
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
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)});
}