From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> 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.pa...@embecosm.com> --- .../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