Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,9 @@ class Stmt : public Visitable

virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
NodeId get_node_id () const { return node_id; }

// TODO: put this in a virtual base class?
virtual NodeId get_node_id () const { return node_id; }

virtual Kind get_stmt_kind () = 0;

Expand Down Expand Up @@ -1536,7 +1538,8 @@ class Type : public Visitable

virtual location_t get_locus () const = 0;

NodeId get_node_id () const { return node_id; }
// TODO: put this in a virtual base class?
virtual NodeId get_node_id () const { return node_id; }
virtual Type *reconstruct_impl () const = 0;

protected:
Expand Down Expand Up @@ -1799,6 +1802,8 @@ class AssociatedItem : public Visitable
virtual bool is_marked_for_strip () const = 0;

virtual location_t get_locus () const = 0;

virtual NodeId get_node_id () const = 0;
};

// Item used in trait declarations - abstract base class
Expand Down
18 changes: 18 additions & 0 deletions gcc/rust/ast/rust-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,13 +865,25 @@ class TypeCastExpr : public OperatorExpr
return *main_or_left_expr;
}

std::unique_ptr<Expr> &get_casted_expr_ptr ()
{
rust_assert (main_or_left_expr != nullptr);
return main_or_left_expr;
}

// TODO: is this better? Or is a "vis_block" better?
TypeNoBounds &get_type_to_cast_to ()
{
rust_assert (type_to_convert_to != nullptr);
return *type_to_convert_to;
}

std::unique_ptr<TypeNoBounds> &get_type_to_cast_to_ptr ()
{
rust_assert (type_to_convert_to != nullptr);
return type_to_convert_to;
}

Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; }

protected:
Expand Down Expand Up @@ -2597,6 +2609,12 @@ class ClosureExprInner : public ClosureExpr
return *closure_inner;
}

std::unique_ptr<Expr> &get_definition_expr_ptr ()
{
rust_assert (closure_inner != nullptr);
return closure_inner;
}

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,9 @@ class TypeAlias : public VisItem, public AssociatedItem

location_t get_locus () const override final { return locus; }

// needed to override AssociatedItem::get_node_id
NodeId get_node_id () const override final { return VisItem::get_node_id (); }

void accept_vis (ASTVisitor &vis) override;

// Invalid if existing type is null, so base stripping on that.
Expand Down Expand Up @@ -2515,6 +2518,9 @@ class ConstantItem : public VisItem, public AssociatedItem

location_t get_locus () const override final { return locus; }

// needed to override AssociatedItem::get_node_id
NodeId get_node_id () const override final { return VisItem::get_node_id (); }

void accept_vis (ASTVisitor &vis) override;

// Invalid if type or expression are null, so base stripping on that.
Expand Down
47 changes: 45 additions & 2 deletions gcc/rust/expand/rust-expand-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,15 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
void
ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
{
NodeId old_expect = expr->get_node_id ();
std::swap (macro_invoc_expect_id, old_expect);

expander.push_context (MacroExpander::ContextType::EXPR);
expr->accept_vis (*this);
expander.pop_context ();

std::swap (macro_invoc_expect_id, old_expect);

auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand ()
&& final_fragment.is_expression_fragment ())
Expand All @@ -342,14 +347,37 @@ ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
void
ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
{
expander.push_context (MacroExpander::ContextType::TYPE);
NodeId old_expect = type->get_node_id ();
std::swap (macro_invoc_expect_id, old_expect);

expander.push_context (MacroExpander::ContextType::TYPE);
type->accept_vis (*this);
expander.pop_context ();

std::swap (macro_invoc_expect_id, old_expect);

auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
type = final_fragment.take_type_fragment ();
}

// HACK: maybe we shouldn't have TypeNoBounds as a base class
void
ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
{
NodeId old_expect = type->get_node_id ();
std::swap (macro_invoc_expect_id, old_expect);

expander.push_context (MacroExpander::ContextType::TYPE);
type->accept_vis (*this);
expander.pop_context ();

std::swap (macro_invoc_expect_id, old_expect);

auto final_fragment = expander.take_expanded_fragment ();
if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
type = std::make_unique<AST::ParenthesisedType> (
final_fragment.take_type_fragment (), BUILTINS_LOCATION);
}

// FIXME: Can this be refactored into a `scoped` method? Which takes a
Expand Down Expand Up @@ -465,6 +493,14 @@ ExpandVisitor::visit (AST::ConstGenericParam &)
void
ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
{
if (macro_invoc_expect_id != macro_invoc.get_node_id ())
{
rust_internal_error_at (
macro_invoc.get_locus (),
"attempting to expand node with id %d into position with node id %d",
(int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
}

// TODO: Can we do the AST fragment replacing here? Probably not, right?
expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
? AST::InvocKind::Semicoloned
Expand Down Expand Up @@ -568,6 +604,13 @@ ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
maybe_expand_expr (expr.get_right_expr_ptr ());
}

void
ExpandVisitor::visit (AST::TypeCastExpr &expr)
{
maybe_expand_expr (expr.get_casted_expr_ptr ());
maybe_expand_type (expr.get_type_to_cast_to_ptr ());
}

void
ExpandVisitor::visit (AST::AssignmentExpr &expr)
{
Expand Down Expand Up @@ -615,7 +658,7 @@ ExpandVisitor::visit (AST::ClosureExprInner &expr)
{
expand_closure_params (expr.get_params ());

visit (expr.get_definition_expr ());
maybe_expand_expr (expr.get_definition_expr_ptr ());
}

void
Expand Down
10 changes: 9 additions & 1 deletion gcc/rust/expand/rust-expand-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ bool is_builtin (AST::Attribute &attr);
class ExpandVisitor : public AST::DefaultASTVisitor
{
public:
ExpandVisitor (MacroExpander &expander) : expander (expander) {}
ExpandVisitor (MacroExpander &expander)
: expander (expander), macro_invoc_expect_id (UNKNOWN_NODEID)
{}

/* Expand all of the macro invocations currently contained in a crate */
void go (AST::Crate &crate);
Expand All @@ -56,6 +58,7 @@ class ExpandVisitor : public AST::DefaultASTVisitor
type : Core guidelines R33, this function reseat the pointer.
*/
void maybe_expand_type (std::unique_ptr<AST::Type> &type);
void maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type);

/**
* Expand all macro invocations in lieu of types within a vector of struct
Expand Down Expand Up @@ -128,7 +131,10 @@ class ExpandVisitor : public AST::DefaultASTVisitor
auto &value = *it;

// Perform expansion
NodeId old_expect = value->get_node_id ();
std::swap (macro_invoc_expect_id, old_expect);
value->accept_vis (*this);
std::swap (macro_invoc_expect_id, old_expect);

auto final_fragment = expander.take_expanded_fragment ();

Expand Down Expand Up @@ -214,6 +220,7 @@ class ExpandVisitor : public AST::DefaultASTVisitor
void visit (AST::ArithmeticOrLogicalExpr &expr) override;
void visit (AST::ComparisonExpr &expr) override;
void visit (AST::LazyBooleanExpr &expr) override;
void visit (AST::TypeCastExpr &expr) override;
void visit (AST::AssignmentExpr &expr) override;
void visit (AST::CompoundAssignmentExpr &expr) override;
void visit (AST::GroupedExpr &expr) override;
Expand Down Expand Up @@ -287,6 +294,7 @@ class ExpandVisitor : public AST::DefaultASTVisitor

private:
MacroExpander &expander;
NodeId macro_invoc_expect_id;
};

} // namespace Rust
Expand Down
11 changes: 11 additions & 0 deletions gcc/testsuite/rust/compile/macros/mbe/macro49.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
#[lang = "sized"]
pub trait Sized {}

#[lang = "fn_once"]
trait FnOnce<Args> {
#[lang = "fn_once_output"]
type Output;

extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

macro_rules! closure {
() => {{
14 + 15
Expand Down
Loading