]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Parse try expressions
authorOwen Avery <powerboat9.gamer@gmail.com>
Wed, 2 Jul 2025 22:48:07 +0000 (18:48 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 5 Aug 2025 14:36:54 +0000 (16:36 +0200)
This doesn't do anything beyond creating TryExpr and parsing them, so
try expressions shouldn't be able to make it past AST lowering yet.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Add visitor
for TryExpr.
* ast/rust-ast-collector.h (TokenCollector::visit): Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h (ASTVisitor::visit): Likewise.
(DefaultASTVisitor::visit): Likewise.
* expand/rust-derive.h (DeriveVisitor::visit): Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h (ASTLoweringBase::visit): Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit):
Likewise.
* resolve/rust-ast-resolve-base.h (ResolverBase::visit):
Likewise.
* ast/rust-ast-full-decls.h (class TryExpr): New forward class
declaration.
* ast/rust-ast.cc (TryExpr::as_string): New function.
(TryExpr::accept_vis): Likewise.
* ast/rust-expr.h (class TryExpr): New class.
* parse/rust-parse.h (Parser::parse_try_expr): New function.
* parse/rust-parse-impl.h (Parser::parse_try_expr): Likewise.
(Parser::null_denotation_not_path): Use parse_try_expr to parse
try expressions.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
14 files changed:
gcc/rust/ast/rust-ast-collector.cc
gcc/rust/ast/rust-ast-collector.h
gcc/rust/ast/rust-ast-full-decls.h
gcc/rust/ast/rust-ast-visitor.cc
gcc/rust/ast/rust-ast-visitor.h
gcc/rust/ast/rust-ast.cc
gcc/rust/ast/rust-expr.h
gcc/rust/expand/rust-derive.h
gcc/rust/hir/rust-ast-lower-base.cc
gcc/rust/hir/rust-ast-lower-base.h
gcc/rust/parse/rust-parse-impl.h
gcc/rust/parse/rust-parse.h
gcc/rust/resolve/rust-ast-resolve-base.cc
gcc/rust/resolve/rust-ast-resolve-base.h

index 5a8d462dbd7b466254cb602920a0bbeeb9bd6c46..0b5f27d36d2ce45de39607c8ae17d529584516c1 100644 (file)
@@ -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)
 {
index cec2365892ec22a8782b1eb507f2a85d4e20329a..e8af5878a2cd337d52ac00b170496ad54d3e17d0 100644 (file)
@@ -289,6 +289,7 @@ public:
   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);
index b410f3ad006e15740e3451df31a51ce290cd8b44..eb1f3ea890c76a167a1240e3abaa35c8b90bd5ef 100644 (file)
@@ -128,6 +128,7 @@ class RangeFullExpr;
 class RangeFromToInclExpr;
 class RangeToInclExpr;
 class ReturnExpr;
+class TryExpr;
 class UnsafeBlockExpr;
 class LoopLabel;
 class BaseLoopExpr;
index c24425bbb381700d2da1adaa659dc913e3f7a41c..fd45fb1060d3d82231afffaad6060cd12c6d98dc 100644 (file)
@@ -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)
 {
index 22fd98b6ea8c2a6c6f4695190810f4041fd9cf00..6111b0548edc7d89119407fc2a14f5190c1b47ce 100644 (file)
@@ -116,6 +116,7 @@ public:
   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;
@@ -307,6 +308,7 @@ public:
   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;
index 916829fe95c05a9d9538303690cdae1aaf1f6f98..4d928ca7a2d5a8dee64b33d78f0b1cd1c4af85ed 100644 (file)
@@ -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
 {
@@ -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)
 {
index 21e856bb1d0e9342a1707607fd51bfd1263478f0..3e50c46e58deaeb0943f83063403c8229fac187d 100644 (file)
@@ -3700,6 +3700,82 @@ protected:
   }
 };
 
+// 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;
 
index ff4f427695ad544a926468f5906bb7dd233309ab..61c7355e7ab2753a29c65a4b7c48122490a63d64 100644 (file)
@@ -159,6 +159,7 @@ private:
   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{};
index 5b35052b665699d0a992775479a9020009729d28..b07ac0c07500b5f86a88750fa1b69f774441a312 100644 (file)
@@ -242,6 +242,9 @@ void
 ASTLoweringBase::visit (AST::ReturnExpr &)
 {}
 void
+ASTLoweringBase::visit (AST::TryExpr &)
+{}
+void
 ASTLoweringBase::visit (AST::UnsafeBlockExpr &)
 {}
 void
index 51912be66b4fef215defa29d48d5cc8d099e79ea..0284ff0c82bbc7930c6de52b650ce0028feb1a54 100644 (file)
@@ -144,6 +144,7 @@ public:
   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;
index 120817b88b8aeeb15902ec3723dc992da558c8f8..9608cd885f4a73c6809d349216613a5256309839 100644 (file)
@@ -7570,6 +7570,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>
@@ -12508,6 +12536,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 ());
index c9b6edb60e9836f2b8ca67d690ae8deac56c5b14..36426d56f8d73cb079fd96bce401fe41881cf424 100644 (file)
@@ -649,6 +649,9 @@ private:
   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);
index 71c4c4834db2aced6d22fe280fcac2cd5e5883ae..05f34bc3f87428b19ba3dd77a5c322c1d32acc24 100644 (file)
@@ -283,6 +283,10 @@ void
 ResolverBase::visit (AST::ReturnExpr &)
 {}
 
+void
+ResolverBase::visit (AST::TryExpr &)
+{}
+
 void
 ResolverBase::visit (AST::UnsafeBlockExpr &)
 {}
index e17bdcb5eaadb432f02cc2c4460790ec4e103535..0cbf78e39abc9e9b2fba12a300a723c14a89845d 100644 (file)
@@ -99,6 +99,7 @@ public:
   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 &);