]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: hir: Handle deferred const inference variables
authorArthur Cohen <arthur.cohen@embecosm.com>
Tue, 8 Jul 2025 12:34:04 +0000 (14:34 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 5 Aug 2025 14:36:57 +0000 (16:36 +0200)
gcc/rust/ChangeLog:

* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Handle defered consts.
* hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise.
(AnonConst::operator=): Likewise.
* hir/tree/rust-hir-expr.h: Likewise.
* hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/deferred_const_inference.rs: New test.

gcc/rust/hir/rust-ast-lower-expr.cc
gcc/rust/hir/tree/rust-hir-expr.cc
gcc/rust/hir/tree/rust-hir-expr.h
gcc/rust/hir/tree/rust-hir-visitor.cc
gcc/rust/typecheck/rust-hir-type-check-expr.cc
gcc/testsuite/rust/compile/deferred_const_inference.rs [new file with mode: 0644]

index 3f3d6007e461fedb3f69b8dd99d0ddb3f018922a..96820fd8c18d9d328e04e0a958cd808687d230d1 100644 (file)
@@ -130,17 +130,24 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr)
 void
 ASTLoweringExpr::visit (AST::AnonConst &expr)
 {
-  auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
-
   auto &mappings = Analysis::Mappings::get ();
   auto crate_num = mappings.get_current_crate ();
   auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
                                        mappings.get_next_hir_id (crate_num),
                                        UNKNOWN_LOCAL_DEFID);
 
-  translated = new HIR::AnonConst (std::move (mapping),
-                                  std::unique_ptr<Expr> (inner_expr),
-                                  expr.get_locus ());
+  if (expr.is_deferred ())
+    {
+      translated = new HIR::AnonConst (std::move (mapping), expr.get_locus ());
+    }
+  else
+    {
+      auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
+
+      translated = new HIR::AnonConst (std::move (mapping),
+                                      std::unique_ptr<Expr> (inner_expr),
+                                      expr.get_locus ());
+    }
 }
 
 void
index 038bfc77f94a1cfe4f614fef8385ba6e9818a0e0..8544ed6708b76c3a29790a5eb2c4efc2a8a8415f 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "rust-hir-expr.h"
 #include "rust-hir-map.h"
+#include "optional.h"
 #include "rust-operators.h"
 #include "rust-hir-stmt.h"
 
@@ -794,22 +795,33 @@ BlockExpr::operator= (BlockExpr const &other)
 AnonConst::AnonConst (Analysis::NodeMapping mappings,
                      std::unique_ptr<Expr> &&expr, location_t locus)
   : ExprWithBlock (std::move (mappings), {}), locus (locus),
-    expr (std::move (expr))
+    kind (Kind::Explicit), expr (std::move (expr))
 {
-  rust_assert (this->expr);
+  rust_assert (this->expr.value ());
 }
 
-AnonConst::AnonConst (const AnonConst &other)
-  : ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr ())
+AnonConst::AnonConst (Analysis::NodeMapping mappings, location_t locus)
+  : ExprWithBlock (std::move (mappings), {}), locus (locus),
+    kind (Kind::DeferredInference), expr (tl::nullopt)
 {}
 
+AnonConst::AnonConst (const AnonConst &other)
+  : ExprWithBlock (other), locus (other.locus), kind (other.kind)
+{
+  if (other.expr)
+    expr = other.expr.value ()->clone_expr ();
+}
+
 AnonConst
 AnonConst::operator= (const AnonConst &other)
 {
   ExprWithBlock::operator= (other);
 
   locus = other.locus;
-  expr = other.expr->clone_expr ();
+  kind = other.kind;
+
+  if (other.expr)
+    expr = other.expr.value ()->clone_expr ();
 
   return *this;
 }
index 028455b987023b989beece76d63308e362e361c5..8e14a7b2912595f76c7c4078413a890e2db16be7 100644 (file)
@@ -1806,8 +1806,16 @@ protected:
 class AnonConst : public ExprWithBlock
 {
 public:
+  enum class Kind
+  {
+    Explicit,
+    DeferredInference
+  };
+
   AnonConst (Analysis::NodeMapping mappings, std::unique_ptr<Expr> &&expr,
             location_t locus = UNKNOWN_LOCATION);
+  AnonConst (Analysis::NodeMapping mappings,
+            location_t locus = UNKNOWN_LOCATION);
   AnonConst (const AnonConst &other);
   AnonConst operator= (const AnonConst &other);
 
@@ -1822,12 +1830,25 @@ public:
   }
 
   location_t get_locus () const override { return locus; }
-  Expr &get_inner_expr () { return *expr; }
-  const Expr &get_inner_expr () const { return *expr; }
+
+  Expr &get_inner_expr ()
+  {
+    rust_assert (kind == Kind::Explicit);
+    return *expr.value ();
+  }
+
+  const Expr &get_inner_expr () const
+  {
+    rust_assert (kind == Kind::Explicit);
+    return *expr.value ();
+  }
+
+  bool is_deferred () const { return kind == Kind::DeferredInference; }
 
 private:
   location_t locus;
-  std::unique_ptr<Expr> expr;
+  Kind kind;
+  tl::optional<std::unique_ptr<Expr>> expr;
 
   AnonConst *clone_expr_with_block_impl () const override
   {
index 447606ebc8c4718455f1842da8921fb99f1d95cc..ece47eba8519a93c35cb000142c26c323fd143af 100644 (file)
@@ -370,7 +370,8 @@ DefaultHIRVisitor::walk (BlockExpr &expr)
 void
 DefaultHIRVisitor::walk (AnonConst &expr)
 {
-  expr.get_inner_expr ().accept_vis (*this);
+  if (!expr.is_deferred ())
+    expr.get_inner_expr ().accept_vis (*this);
 }
 
 void
@@ -1176,4 +1177,4 @@ DefaultHIRVisitor::walk (BareFunctionType &type)
 }
 
 } // namespace HIR
-} // namespace Rust
\ No newline at end of file
+} // namespace Rust
index 5db0e5690c97d6c8332942cdc6d9a1219b35b2da..9f8d31109b15fef358006d111b06012b16017d9f 100644 (file)
@@ -664,6 +664,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
 void
 TypeCheckExpr::visit (HIR::AnonConst &expr)
 {
+  // FIXME: How do we typecheck a deferred inference const?
+
+  rust_assert (!expr.is_deferred ());
+
   infered = TypeCheckExpr::Resolve (expr.get_inner_expr ());
 }
 
diff --git a/gcc/testsuite/rust/compile/deferred_const_inference.rs b/gcc/testsuite/rust/compile/deferred_const_inference.rs
new file mode 100644 (file)
index 0000000..25a3b17
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+// #![feature(generic_arg_infer)]
+
+fn main() {
+    let a: [u32; _] = [15u32];
+}