Skip to content

Commit 669fdca

Browse files
committed
---
yaml --- r: 14827 b: refs/heads/try c: fc50abe h: refs/heads/master i: 14825: add6511 14823: 28fe3dc v: v3
1 parent e032f83 commit 669fdca

File tree

3 files changed

+65
-13
lines changed

3 files changed

+65
-13
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: aeb445b2ea25f9629df1d5d8fbd2906a92c8e719
5+
refs/heads/try: fc50abe6c54d892e4cb7fbb93f959ba14ed68810
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/rustc/middle/region.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ type region_map = {
3838
/* Mapping from a region name to its function. */
3939
region_name_to_fn: hashmap<ast::def_id,ast::node_id>,
4040
/* Mapping from an AST type node to the region that `&` resolves to. */
41-
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>
41+
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>,
42+
/* Mapping from a call site (or `bind` site) to its containing block. */
43+
call_site_to_block: hashmap<ast::node_id,ast::node_id>
4244
};
4345

4446
type ctxt = {
@@ -237,6 +239,16 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
237239
in_alt: false with cx};
238240
visit::visit_expr(expr, new_cx, visitor);
239241
}
242+
ast::expr_call(_, _, _) | ast::expr_bind(_, _) {
243+
// Record the block that this call appears in.
244+
alt cx.parent {
245+
pa_block(blk_id) {
246+
cx.region_map.call_site_to_block.insert(expr.id, blk_id);
247+
}
248+
_ { cx.sess.span_bug(expr.span, "expr outside of block?!"); }
249+
}
250+
visit::visit_expr(expr, cx, visitor);
251+
}
240252
_ { visit::visit_expr(expr, cx, visitor); }
241253
}
242254
}
@@ -263,7 +275,8 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
263275
local_blocks: map::new_int_hash(),
264276
region_name_to_fn: new_def_hash(),
265277
ast_type_to_inferred_region:
266-
map::new_int_hash()},
278+
map::new_int_hash(),
279+
call_site_to_block: map::new_int_hash()},
267280
mut bindings: @list::nil,
268281
mut queued_locals: [],
269282
parent: pa_crate,

branches/try/src/rustc/middle/typeck.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,8 +1970,42 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
19701970

19711971
// A generic function to factor out common logic from call and bind
19721972
// expressions.
1973-
fn check_call_or_bind(fcx: @fn_ctxt, sp: span, fty: ty::t,
1974-
args: [option<@ast::expr>]) -> bool {
1973+
fn check_call_or_bind(fcx: @fn_ctxt, sp: span, id: ast::node_id,
1974+
fty: ty::t, args: [option<@ast::expr>]) -> bool {
1975+
// Replaces "caller" regions in the arguments with the local region.
1976+
fn instantiate_caller_regions(fcx: @fn_ctxt, id: ast::node_id,
1977+
args: [ty::arg]) -> [ty::arg] {
1978+
let site_to_block = fcx.ccx.tcx.region_map.call_site_to_block;
1979+
let block_id = alt site_to_block.find(id) {
1980+
none {
1981+
// This can happen for those expressions that are
1982+
// synthesized during typechecking; e.g. during
1983+
// check_constraints().
1984+
ret args;
1985+
}
1986+
some(block_id) { block_id }
1987+
};
1988+
1989+
let region = ty::re_block(block_id);
1990+
ret vec::map(args) {|arg|
1991+
if ty::type_has_rptrs(arg.ty) {
1992+
let ty = ty::fold_ty(fcx.ccx.tcx, ty::fm_rptr({|r|
1993+
alt r {
1994+
ty::re_caller(_) {
1995+
// FIXME: We should not recurse into nested
1996+
// function types here.
1997+
region
1998+
}
1999+
_ { r }
2000+
}
2001+
}), arg.ty);
2002+
{ty: ty with arg}
2003+
} else {
2004+
arg
2005+
}
2006+
};
2007+
}
2008+
19752009
let sty = structure_of(fcx, sp, fty);
19762010
// Grab the argument types
19772011
let arg_tys = alt sty {
@@ -2009,6 +2043,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
20092043
arg_tys = vec::from_elem(supplied_arg_count, dummy);
20102044
}
20112045

2046+
arg_tys = instantiate_caller_regions(fcx, id, arg_tys);
2047+
20122048
// Check the arguments.
20132049
// We do this in a pretty awful way: first we typecheck any arguments
20142050
// that are not anonymous functions, then we typecheck the anonymous
@@ -2049,7 +2085,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
20492085
}
20502086

20512087
// A generic function for checking call expressions
2052-
fn check_call(fcx: @fn_ctxt, sp: span, f: @ast::expr, args: [@ast::expr])
2088+
fn check_call(fcx: @fn_ctxt, sp: span, id: ast::node_id, f: @ast::expr,
2089+
args: [@ast::expr])
20532090
-> bool {
20542091
let args_opt_0: [option<@ast::expr>] = [];
20552092
for arg: @ast::expr in args {
@@ -2058,13 +2095,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
20582095

20592096
let bot = check_expr(fcx, f);
20602097
// Call the generic checker.
2061-
bot | check_call_or_bind(fcx, sp, expr_ty(fcx.ccx.tcx, f), args_opt_0)
2098+
bot | check_call_or_bind(fcx, sp, id, expr_ty(fcx.ccx.tcx, f),
2099+
args_opt_0)
20622100
}
20632101

20642102
// A generic function for doing all of the checking for call expressions
2065-
fn check_call_full(fcx: @fn_ctxt, sp: span, f: @ast::expr,
2066-
args: [@ast::expr], id: ast::node_id) -> bool {
2067-
let bot = check_call(fcx, sp, f, args);
2103+
fn check_call_full(fcx: @fn_ctxt, sp: span, id: ast::node_id,
2104+
f: @ast::expr, args: [@ast::expr]) -> bool {
2105+
let bot = check_call(fcx, sp, id, f, args);
20682106
/* here we're kind of hosed, as f can be any expr
20692107
need to restrict it to being an explicit expr_path if we're
20702108
inside a pure function, and need an environment mapping from
@@ -2145,7 +2183,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
21452183
alt lookup_method(fcx, op_ex, callee_id, opname, self_t, []) {
21462184
some(origin) {
21472185
let method_ty = ty::node_id_to_type(fcx.ccx.tcx, callee_id);
2148-
check_call_or_bind(fcx, op_ex.span, method_ty, args);
2186+
check_call_or_bind(fcx, op_ex.span, op_ex.id, method_ty, args);
21492187
fcx.ccx.method_map.insert(op_ex.id, origin);
21502188
some(ty::ty_fn_ret(method_ty))
21512189
}
@@ -2472,7 +2510,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
24722510
ast::expr_bind(f, args) {
24732511
// Call the generic checker.
24742512
bot = check_expr(fcx, f);
2475-
bot |= check_call_or_bind(fcx, expr.span, expr_ty(tcx, f), args);
2513+
bot |= check_call_or_bind(fcx, expr.span, expr.id, expr_ty(tcx, f),
2514+
args);
24762515

24772516
// Pull the argument and return types out.
24782517
let proto, arg_tys, rt, cf, constrs;
@@ -2518,7 +2557,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
25182557
write_ty(tcx, id, ft);
25192558
}
25202559
ast::expr_call(f, args, _) {
2521-
bot = check_call_full(fcx, expr.span, f, args, expr.id);
2560+
bot = check_call_full(fcx, expr.span, expr.id, f, args);
25222561
}
25232562
ast::expr_cast(e, t) {
25242563
bot = check_expr(fcx, e);

0 commit comments

Comments
 (0)