From 46aec2c96002a57f50dfef933b55a5d44bf2573c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sun, 11 Mar 2012 17:01:28 -0700 Subject: [PATCH] rustc: Record the parent function of each function --- src/rustc/middle/region.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index 7b4b21e5f9c..0a9bb92527d 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -12,6 +12,8 @@ import std::map::hashmap; type region_map = { /* Mapping from a block to its parent block, if there is one. */ parent_blocks: hashmap, + /* Mapping from a lambda to its parent function, if there is one. */ + parent_fns: hashmap, /* Mapping from a region type in the AST to its resolved region. */ ast_type_to_region: hashmap, /* Mapping from a local variable to its containing block. */ @@ -40,7 +42,8 @@ type ctxt = { */ mut queued_locals: [ast::node_id], - parent: parent + parent: parent, + mut parent_fn: option }; // Returns true if `subblock` is equal to or is lexically nested inside @@ -206,10 +209,23 @@ fn resolve_pat(pat: @ast::pat, cx: ctxt, visitor: visit::vt) { visit::visit_pat(pat, cx, visitor); } +fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt) { + alt expr.node { + ast::expr_fn(_, _, _, _) | ast::expr_fn_block(_, _) { + let parent_fns = cx.region_map.parent_fns; + parent_fns.insert(expr.id, option::get(cx.parent_fn)); + let new_cx = {parent_fn: some(expr.id) with cx}; + visit::visit_expr(expr, new_cx, visitor); + } + _ { visit::visit_expr(expr, cx, visitor); } + } +} + fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt) { // Items create a new outer block scope as far as we're concerned. let new_cx: ctxt = {names_in_scope: map::new_str_hash(), - parent: pa_item(item.id) + parent: pa_item(item.id), + parent_fn: some(item.id) with cx}; visit::visit_item(item, new_cx, visitor); } @@ -219,17 +235,20 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate) let cx: ctxt = {sess: sess, def_map: def_map, region_map: @{parent_blocks: map::new_int_hash(), + parent_fns: map::new_int_hash(), ast_type_to_region: map::new_int_hash(), local_blocks: map::new_int_hash()}, names_in_scope: map::new_str_hash(), mut queued_locals: [], - parent: pa_crate}; + parent: pa_crate, + mut parent_fn: none}; let visitor = visit::mk_vt(@{ visit_block: resolve_block, visit_item: resolve_item, visit_ty: resolve_ty, visit_arm: resolve_arm, - visit_pat: resolve_pat + visit_pat: resolve_pat, + visit_expr: resolve_expr with *visit::default_visitor() }); visit::visit_crate(*crate, cx, visitor);