From: Pierre-Emmanuel Patry <[email protected]>
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 <[email protected]>
---
.../resolve/rust-late-name-resolver-2.0.cc | 13 ++++++++++++
.../resolve/rust-late-name-resolver-2.0.h | 2 ++
gcc/rust/resolve/rust-name-resolver.cc | 2 ++
.../typecheck/rust-hir-type-check-expr.cc | 20 ++++++++++++++++++-
gcc/rust/util/rust-hir-map.cc | 20 +++++++++++++++++++
gcc/rust/util/rust-hir-map.h | 5 +++++
6 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index e3d95e5dd7b..0779736809e 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -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
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 95ad338417c..bf6d1935d3d 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -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 */
diff --git a/gcc/rust/resolve/rust-name-resolver.cc
b/gcc/rust/resolve/rust-name-resolver.cc
index 0f5b1084774..97ee2d37ded 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -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;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 113f43f6c72..23773f13836 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -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);
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index ac18e575765..39c3a98f16b 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -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
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 8ea86466220..d654a1dfadc 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -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
--
2.45.2