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 24, 2025
1 parent dd750c9 commit 2b47316
Show file tree
Hide file tree
Showing 6 changed files with 61 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 @@ -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
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 @@ -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
5 changes: 5 additions & 0 deletions gcc/rust/util/rust-hir-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ class Mappings

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 ();
Expand Down Expand Up @@ -434,6 +436,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 2b47316

Please sign in to comment.