diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-12-04 22:02:22 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-04 22:02:22 +0000 |
commit | e39fadcd0aa4d52d53667e2adad9a6677f7e9adf (patch) | |
tree | b412e8330dfb14001b7c66483520fe99e029f4d2 /gcc/rust/backend/rust-compile-context.cc | |
parent | 22329b03a6e0a3381d907745205012cf290b3c2a (diff) | |
parent | 3053ec366093560a6269aaace61ce77fb8710b01 (diff) | |
download | gcc-e39fadcd0aa4d52d53667e2adad9a6677f7e9adf.zip gcc-e39fadcd0aa4d52d53667e2adad9a6677f7e9adf.tar.gz gcc-e39fadcd0aa4d52d53667e2adad9a6677f7e9adf.tar.bz2 |
Merge #1611
1611: Initial state capture for closures r=philberty a=philberty
This patch set adds the initial support closure captures, move semantics are not
handled here. We track what variables are being captured by a closure during
name resolution so that when a VAR_DECL is resolved, we check if we are inside
a closure context node_id which is the same id as its associated rib id. So when
we resolve a name that resides in an outermost rib we can add this to set of
node-id's that are captured by this closure.
There is a gap here for the case where we need to check if it is inside a nested
function and that function contains closures which could wrongly capture variables
in the enclosing function. This will also be a problem for nested functions in general.
Fixes #195
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend/rust-compile-context.cc')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-context.cc b/gcc/rust/backend/rust-compile-context.cc index cb2addf6..0687398 100644 --- a/gcc/rust/backend/rust-compile-context.cc +++ b/gcc/rust/backend/rust-compile-context.cc @@ -142,5 +142,52 @@ Context::type_hasher (tree type) return hstate.end (); } +void +Context::push_closure_context (HirId id) +{ + auto it = closure_bindings.find (id); + rust_assert (it == closure_bindings.end ()); + + closure_bindings.insert ({id, {}}); + closure_scope_bindings.push_back (id); +} + +void +Context::pop_closure_context () +{ + rust_assert (!closure_scope_bindings.empty ()); + + HirId ref = closure_scope_bindings.back (); + closure_scope_bindings.pop_back (); + closure_bindings.erase (ref); +} + +void +Context::insert_closure_binding (HirId id, tree expr) +{ + rust_assert (!closure_scope_bindings.empty ()); + + HirId ref = closure_scope_bindings.back (); + closure_bindings[ref].insert ({id, expr}); +} + +bool +Context::lookup_closure_binding (HirId id, tree *expr) +{ + if (closure_scope_bindings.empty ()) + return false; + + HirId ref = closure_scope_bindings.back (); + auto it = closure_bindings.find (ref); + rust_assert (it != closure_bindings.end ()); + + auto iy = it->second.find (id); + if (iy == it->second.end ()) + return false; + + *expr = iy->second; + return true; +} + } // namespace Compile } // namespace Rust |