Skip to content

Commit

Permalink
Add environment capture to NR2
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
P-E-P committed Jan 20, 2025
1 parent 5db9ab5 commit 22cb4a2
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 1 deletion.
13 changes: 13 additions & 0 deletions gcc/rust/resolve/rust-late-name-resolver-2.0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,5 +370,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
2 changes: 2 additions & 0 deletions gcc/rust/resolve/rust-late-name-resolver-2.0.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "rust-ast-full.h"
#include "rust-default-resolver.h"
#include "rust-expr.h"

namespace Rust {
namespace Resolver2_0 {
Expand Down Expand Up @@ -55,6 +56,7 @@ class Late : public DefaultResolver
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 */
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/resolve/rust-name-resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 19 additions & 1 deletion gcc/rust/typecheck/rust-hir-type-check-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);

Expand Down
20 changes: 20 additions & 0 deletions gcc/rust/util/rust-hir-map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1299,5 +1299,25 @@ Mappings::lookup_lang_item_node (LangItem::Kind item_type)
return it->second;
}

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
6 changes: 6 additions & 0 deletions gcc/rust/util/rust-hir-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ class Mappings
tl::optional<HIR::TraitItem *>
lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);

void add_capture (NodeId closure, NodeId definition);
tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure);

private:
Mappings ();

Expand Down Expand Up @@ -427,6 +430,9 @@ class Mappings

// 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
Expand Down

0 comments on commit 22cb4a2

Please sign in to comment.