when collecting free vars, track the span where it is used too
This commit is contained in:
parent
98cbbbb642
commit
b0f1a5f051
|
@ -10,12 +10,17 @@ import syntax::codemap::span;
|
|||
|
||||
export annotate_freevars;
|
||||
export freevar_map;
|
||||
export freevar_info;
|
||||
export get_freevars;
|
||||
export has_freevars;
|
||||
|
||||
// A vector of defs representing the free variables referred to in a function.
|
||||
// (The def_upvar will already have been stripped).
|
||||
type freevar_info = @[ast::def];
|
||||
type freevar_entry = {
|
||||
def: ast::def, //< The variable being accessed free.
|
||||
span: span //< First span where it is accessed (there can be multiple)
|
||||
};
|
||||
type freevar_info = @[@freevar_entry];
|
||||
type freevar_map = hashmap<ast::node_id, freevar_info>;
|
||||
|
||||
// Searches through part of the AST for all references to locals or
|
||||
|
@ -50,7 +55,7 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
|
|||
if i == depth { // Made it to end of loop
|
||||
let dnum = ast_util::def_id_of_def(def).node;
|
||||
if !seen.contains_key(dnum) {
|
||||
*refs += [def];
|
||||
*refs += [@{def:def, span:expr.span}];
|
||||
seen.insert(dnum, ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|||
fn check_free_vars(e: @expr,
|
||||
cx: ctx,
|
||||
check_fn: fn(ctx, ty::t, sp: span)) {
|
||||
for free in *freevars::get_freevars(cx.tcx, e.id) {
|
||||
let id = ast_util::def_id_of_def(free).node;
|
||||
for @{def, span} in *freevars::get_freevars(cx.tcx, e.id) {
|
||||
let id = ast_util::def_id_of_def(def).node;
|
||||
let ty = ty::node_id_to_type(cx.tcx, id);
|
||||
check_fn(cx, ty, e.span);
|
||||
check_fn(cx, ty, span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import llvm::{ValueRef, TypeRef};
|
|||
import trans_common::*;
|
||||
import trans_build::*;
|
||||
import trans::*;
|
||||
import middle::freevars::get_freevars;
|
||||
import middle::freevars::{get_freevars, freevar_info};
|
||||
import option::{some, none};
|
||||
import back::abi;
|
||||
import syntax::codemap::span;
|
||||
|
@ -261,16 +261,16 @@ fn store_environment(
|
|||
// Given a context and a list of upvars, build a closure. This just
|
||||
// collects the upvars and packages them up for store_environment.
|
||||
fn build_closure(cx: @block_ctxt,
|
||||
upvars: @[ast::def],
|
||||
upvars: freevar_info,
|
||||
ck: ty::closure_kind)
|
||||
-> closure_result {
|
||||
// If we need to, package up the iterator body to call
|
||||
let env_vals = [];
|
||||
let tcx = bcx_tcx(cx);
|
||||
// Package up the upvars
|
||||
vec::iter(*upvars) { |def|
|
||||
let lv = trans_local_var(cx, def);
|
||||
let nid = ast_util::def_id_of_def(def).node;
|
||||
vec::iter(*upvars) { |upvar|
|
||||
let lv = trans_local_var(cx, upvar.def);
|
||||
let nid = ast_util::def_id_of_def(upvar.def).node;
|
||||
let ty = ty::node_id_to_monotype(tcx, nid);
|
||||
alt ck {
|
||||
ty::closure_block. { ty = ty::mk_mut_ptr(tcx, ty); }
|
||||
|
@ -287,7 +287,7 @@ fn build_closure(cx: @block_ctxt,
|
|||
fn load_environment(enclosing_cx: @block_ctxt,
|
||||
fcx: @fn_ctxt,
|
||||
boxed_closure_ty: ty::t,
|
||||
upvars: @[ast::def],
|
||||
upvars: freevar_info,
|
||||
ck: ty::closure_kind) {
|
||||
let bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
|
||||
|
||||
|
@ -311,7 +311,7 @@ fn load_environment(enclosing_cx: @block_ctxt,
|
|||
|
||||
// Populate the upvars from the environment.
|
||||
let path = [0, abi::box_rc_field_body, abi::closure_elt_bindings];
|
||||
vec::iteri(*upvars) { |i, upvar_def|
|
||||
vec::iteri(*upvars) { |i, upvar|
|
||||
check type_is_tup_like(bcx, boxed_closure_ty);
|
||||
let upvarptr =
|
||||
GEP_tup_like(bcx, boxed_closure_ty, llclosure, path + [i as int]);
|
||||
|
@ -321,7 +321,7 @@ fn load_environment(enclosing_cx: @block_ctxt,
|
|||
ty::closure_block. { llupvarptr = Load(bcx, llupvarptr); }
|
||||
ty::closure_send. | ty::closure_shared. { }
|
||||
}
|
||||
let def_id = ast_util::def_id_of_def(upvar_def);
|
||||
let def_id = ast_util::def_id_of_def(upvar.def);
|
||||
fcx.llupvars.insert(def_id.node, llupvarptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
|
|||
expr_fn(f, _) { // NDM captures
|
||||
let rslt = expr_pp(fcx.ccx, e);
|
||||
clear_pp(rslt);
|
||||
for def in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
|
||||
for @{def, span} in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
|
||||
log ("handle_var_def: def=", def);
|
||||
handle_var_def(fcx, rslt, def, "upvar");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// error-pattern: not a sendable value
|
||||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _f = sendfn(y: uint) -> uint { ret *x+y; };
|
||||
}
|
Loading…
Reference in a new issue