Skip to content

Parse try expressions #3870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2025
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
7 changes: 7 additions & 0 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,13 @@ TokenCollector::visit (ReturnExpr &expr)
visit (expr.get_returned_expr ());
}

void
TokenCollector::visit (TryExpr &expr)
{
push (Rust::Token::make (TRY, expr.get_locus ()));
visit (expr.get_block_expr ());
}

void
TokenCollector::visit (UnsafeBlockExpr &expr)
{
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/ast/rust-ast-collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class TokenCollector : public ASTVisitor
void visit (RangeFromToInclExpr &expr);
void visit (RangeToInclExpr &expr);
void visit (ReturnExpr &expr);
void visit (TryExpr &expr);
void visit (BoxExpr &expr);
void visit (UnsafeBlockExpr &expr);
void visit (LoopExpr &expr);
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/ast/rust-ast-full-decls.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class RangeFullExpr;
class RangeFromToInclExpr;
class RangeToInclExpr;
class ReturnExpr;
class TryExpr;
class UnsafeBlockExpr;
class LoopLabel;
class BaseLoopExpr;
Expand Down
7 changes: 7 additions & 0 deletions gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,13 @@ DefaultASTVisitor::visit (AST::ReturnExpr &expr)
visit (expr.get_returned_expr ());
}

void
DefaultASTVisitor::visit (AST::TryExpr &expr)
{
visit_outer_attrs (expr);
visit (expr.get_block_expr ());
}

void
DefaultASTVisitor::visit (AST::BoxExpr &expr)
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/ast/rust-ast-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class ASTVisitor
virtual void visit (RangeFromToInclExpr &expr) = 0;
virtual void visit (RangeToInclExpr &expr) = 0;
virtual void visit (ReturnExpr &expr) = 0;
virtual void visit (TryExpr &expr) = 0;
virtual void visit (BoxExpr &expr) = 0;
virtual void visit (UnsafeBlockExpr &expr) = 0;
virtual void visit (LoopExpr &expr) = 0;
Expand Down Expand Up @@ -307,6 +308,7 @@ class DefaultASTVisitor : public ASTVisitor
virtual void visit (AST::RangeFromToInclExpr &expr) override;
virtual void visit (AST::RangeToInclExpr &expr) override;
virtual void visit (AST::ReturnExpr &expr) override;
virtual void visit (AST::TryExpr &expr) override;
virtual void visit (AST::BoxExpr &expr) override;
virtual void visit (AST::UnsafeBlockExpr &expr) override;
virtual void visit (AST::LoopExpr &expr) override;
Expand Down
19 changes: 19 additions & 0 deletions gcc/rust/ast/rust-ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,19 @@ ReturnExpr::as_string () const
return str;
}

std::string
TryExpr::as_string () const
{
/* TODO: find way to incorporate outer attrs - may have to represent in
* different style (i.e. something more like BorrowExpr: \n outer attrs) */

std::string str ("try ");

str += block_expr->as_string ();

return str;
}

std::string
RangeToExpr::as_string () const
{
Expand Down Expand Up @@ -4604,6 +4617,12 @@ ReturnExpr::accept_vis (ASTVisitor &vis)
vis.visit (*this);
}

void
TryExpr::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
}

void
UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
{
Expand Down
76 changes: 76 additions & 0 deletions gcc/rust/ast/rust-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3700,6 +3700,82 @@ class ReturnExpr : public ExprWithoutBlock
}
};

// Try expression AST node representation
class TryExpr : public ExprWithBlock
{
std::vector<Attribute> outer_attrs;
std::unique_ptr<BlockExpr> block_expr;
location_t locus;

// TODO: find another way to store this to save memory?
bool marked_for_strip = false;

public:
std::string as_string () const override;

// Constructor for ReturnExpr.
TryExpr (std::unique_ptr<BlockExpr> block_expr,
std::vector<Attribute> outer_attribs, location_t locus)
: outer_attrs (std::move (outer_attribs)),
block_expr (std::move (block_expr)), locus (locus)
{
rust_assert (this->block_expr);
}

// Copy constructor with clone
TryExpr (TryExpr const &other)
: ExprWithBlock (other), outer_attrs (other.outer_attrs),
block_expr (other.block_expr->clone_block_expr ()), locus (other.locus),
marked_for_strip (other.marked_for_strip)
{}

// Overloaded assignment operator to clone return_expr pointer
TryExpr &operator= (TryExpr const &other)
{
ExprWithBlock::operator= (other);
locus = other.locus;
marked_for_strip = other.marked_for_strip;
outer_attrs = other.outer_attrs;

block_expr = other.block_expr->clone_block_expr ();

return *this;
}

// move constructors
TryExpr (TryExpr &&other) = default;
TryExpr &operator= (TryExpr &&other) = default;

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

void accept_vis (ASTVisitor &vis) override;

// Can't think of any invalid invariants, so store boolean.
void mark_for_strip () override { marked_for_strip = true; }
bool is_marked_for_strip () const override { return marked_for_strip; }

// TODO: is this better? Or is a "vis_block" better?
BlockExpr &get_block_expr () { return *block_expr; }

const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }

void set_outer_attrs (std::vector<Attribute> new_attrs) override
{
outer_attrs = std::move (new_attrs);
}

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

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
TryExpr *clone_expr_with_block_impl () const override
{
return new TryExpr (*this);
}
};

// Forward decl - defined in rust-macro.h
class MacroInvocation;

Expand Down
1 change: 1 addition & 0 deletions gcc/rust/expand/rust-derive.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class DeriveVisitor : public AST::ASTVisitor
virtual void visit (RangeFromToInclExpr &expr) override final{};
virtual void visit (RangeToInclExpr &expr) override final{};
virtual void visit (ReturnExpr &expr) override final{};
virtual void visit (TryExpr &expr) override final{};
virtual void visit (BoxExpr &expr) override final{};
virtual void visit (UnsafeBlockExpr &expr) override final{};
virtual void visit (LoopExpr &expr) override final{};
Expand Down
3 changes: 3 additions & 0 deletions gcc/rust/hir/rust-ast-lower-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ void
ASTLoweringBase::visit (AST::ReturnExpr &)
{}
void
ASTLoweringBase::visit (AST::TryExpr &)
{}
void
ASTLoweringBase::visit (AST::UnsafeBlockExpr &)
{}
void
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/hir/rust-ast-lower-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class ASTLoweringBase : public AST::ASTVisitor
virtual void visit (AST::RangeToInclExpr &expr) override;
virtual void visit (AST::BoxExpr &expr) override;
virtual void visit (AST::ReturnExpr &expr) override;
virtual void visit (AST::TryExpr &expr) override;
virtual void visit (AST::UnsafeBlockExpr &expr) override;
virtual void visit (AST::LoopExpr &expr) override;
virtual void visit (AST::WhileLoopExpr &expr) override;
Expand Down
31 changes: 31 additions & 0 deletions gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7568,6 +7568,34 @@ Parser<ManagedTokenSource>::parse_return_expr (AST::AttrVec outer_attrs,
locus));
}

// Parses a try expression.
template <typename ManagedTokenSource>
std::unique_ptr<AST::TryExpr>
Parser<ManagedTokenSource>::parse_try_expr (AST::AttrVec outer_attrs,
location_t pratt_parsed_loc)
{
location_t locus = pratt_parsed_loc;
if (locus == UNKNOWN_LOCATION)
{
locus = lexer.peek_token ()->get_locus ();
skip_token (TRY);
}

std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();

if (!block_expr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse try block expression");
add_error (std::move (error));

return nullptr;
}

return std::unique_ptr<AST::TryExpr> (
new AST::TryExpr (std::move (block_expr), std::move (outer_attrs), locus));
}

/* Parses a break expression (including any label to break to AND any return
* expression). */
template <typename ManagedTokenSource>
Expand Down Expand Up @@ -12506,6 +12534,9 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
case RETURN_KW:
// FIXME: is this really a null denotation expression?
return parse_return_expr (std::move (outer_attrs), tok->get_locus ());
case TRY:
// FIXME: is this really a null denotation expression?
return parse_try_expr (std::move (outer_attrs), tok->get_locus ());
case BREAK:
// FIXME: is this really a null denotation expression?
return parse_break_expr (std::move (outer_attrs), tok->get_locus ());
Expand Down
3 changes: 3 additions & 0 deletions gcc/rust/parse/rust-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,9 @@ template <typename ManagedTokenSource> class Parser
std::unique_ptr<AST::ReturnExpr>
parse_return_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::TryExpr>
parse_try_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
std::unique_ptr<AST::BreakExpr>
parse_break_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/resolve/rust-ast-resolve-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ void
ResolverBase::visit (AST::ReturnExpr &)
{}

void
ResolverBase::visit (AST::TryExpr &)
{}

void
ResolverBase::visit (AST::UnsafeBlockExpr &)
{}
Expand Down
1 change: 1 addition & 0 deletions gcc/rust/resolve/rust-ast-resolve-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class ResolverBase : public AST::ASTVisitor
void visit (AST::RangeToInclExpr &);
void visit (AST::BoxExpr &);
void visit (AST::ReturnExpr &);
void visit (AST::TryExpr &);
void visit (AST::UnsafeBlockExpr &);
void visit (AST::LoopExpr &);
void visit (AST::WhileLoopExpr &);
Expand Down
Loading