]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add environment capture to NR2
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Mon, 20 Jan 2025 12:49:25 +0000 (13:49 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 24 Mar 2025 12:06:53 +0000 (13:06 +0100)
The compiler was still relying on NR1 for closure captures when using nr2
even though the resolver was not used and thus it's state empty.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add environment
collection.
* resolve/rust-late-name-resolver-2.0.h: Add function prototype.
* resolve/rust-name-resolver.cc (Resolver::get_captures): Add assertion
to prevent NR2 usage with nr1 capture functions.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Use
nr2 captures.
* util/rust-hir-map.cc (Mappings::add_capture): Add function to
register capture for a given closure.
(Mappings::lookup_captures):  Add a function to lookup all captures
available for a given closure.
* util/rust-hir-map.h: Add function prototypes.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/resolve/rust-late-name-resolver-2.0.cc
gcc/rust/resolve/rust-late-name-resolver-2.0.h
gcc/rust/resolve/rust-name-resolver.cc
gcc/rust/typecheck/rust-hir-type-check-expr.cc
gcc/rust/util/rust-hir-map.cc
gcc/rust/util/rust-hir-map.h

index e3d95e5dd7bddb4298f5425abdc933b24aed278d..0779736809e6f22272b2b5edddabe60799a7c6dc 100644 (file)
@@ -390,5 +390,18 @@ Late::visit (AST::GenericArg &arg)
   DefaultResolver::visit (arg);
 }
 
+void
+Late::visit (AST::ClosureExprInner &closure)
+{
+  auto vals = ctx.values.peek ().get_values ();
+  for (auto &val : vals)
+    {
+      ctx.mappings.add_capture (closure.get_node_id (),
+                               val.second.get_node_id ());
+    }
+
+  DefaultResolver::visit (closure);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
index 95ad338417cda0be9c4dbb21422c1d606748a7d3..bf6d1935d3dfb3468c6754c0034b5f8b10578591 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "rust-ast-full.h"
 #include "rust-default-resolver.h"
+#include "rust-expr.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -55,6 +56,7 @@ public:
   void visit (AST::StructStruct &) override;
   void visit (AST::GenericArgs &) override;
   void visit (AST::GenericArg &);
+  void visit (AST::ClosureExprInner &) override;
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
index 0f5b108477427f980ab59f065ce284af9d0fcb38..97ee2d37dedbe2fc4f2445864839a7015367b44b 100644 (file)
@@ -674,6 +674,8 @@ Resolver::decl_needs_capture (NodeId decl_rib_node_id,
 const std::set<NodeId> &
 Resolver::get_captures (NodeId id) const
 {
+  rust_assert (!flag_name_resolution_2_0);
+
   auto it = closures_capture_mappings.find (id);
   rust_assert (it != closures_capture_mappings.end ());
   return it->second;
index 113f43f6c724ce1576cc1e1b533b9d7550692152..23773f138367799e5369f68d174312b386271aeb 100644 (file)
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+#include "rust-system.h"
 #include "rust-tyty-call.h"
 #include "rust-hir-type-check-struct-field.h"
 #include "rust-hir-path-probe.h"
@@ -1599,7 +1600,24 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
 
   // generate the closure type
   NodeId closure_node_id = expr.get_mappings ().get_nodeid ();
-  const std::set<NodeId> &captures = resolver->get_captures (closure_node_id);
+
+  // Resolve closure captures
+
+  std::set<NodeId> captures;
+  if (flag_name_resolution_2_0)
+    {
+      auto &nr_ctx = const_cast<Resolver2_0::NameResolutionContext &> (
+       Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+      if (auto opt_cap = nr_ctx.mappings.lookup_captures (closure_node_id))
+       for (auto cap : opt_cap.value ())
+         captures.insert (cap);
+    }
+  else
+    {
+      captures = resolver->get_captures (closure_node_id);
+    }
+
   infered = new TyTy::ClosureType (ref, id, ident, closure_args, result_type,
                                   subst_refs, captures);
 
index ac18e575765aece35ea6c17bd8d71277e8d6b6f5..39c3a98f16bc47f04a7161336aed975d1511f1b8 100644 (file)
@@ -1321,5 +1321,25 @@ Mappings::get_auto_traits ()
   return auto_traits;
 }
 
+void
+Mappings::add_capture (NodeId closure, NodeId definition)
+{
+  auto cap = captures.find (closure);
+  if (cap == captures.end ())
+    captures[closure] = {definition};
+  else
+    cap->second.push_back (definition);
+}
+
+tl::optional<std::vector<NodeId>>
+Mappings::lookup_captures (NodeId closure)
+{
+  auto cap = captures.find (closure);
+  if (cap == captures.end ())
+    return tl::nullopt;
+  else
+    return cap->second;
+}
+
 } // namespace Analysis
 } // namespace Rust
index 8ea86466220ebd63975e2353d6711751e8615856..d654a1dfadcecdeaddbd680569f06eddbc0d3807 100644 (file)
@@ -344,6 +344,8 @@ public:
 
   void insert_auto_trait (HIR::Trait *trait);
   std::vector<HIR::Trait *> &get_auto_traits ();
+  void add_capture (NodeId closure, NodeId definition);
+  tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);
 
 private:
   Mappings ();
@@ -434,6 +436,9 @@ private:
 
   // AST mappings
   std::map<NodeId, AST::Item *> ast_item_mappings;
+
+  // Closure AST NodeId -> vector of Definition node ids
+  std::unordered_map<NodeId, std::vector<NodeId>> captures;
 };
 
 } // namespace Analysis