From c13f0874542aa47361fa82cf280f6d8c3d46d84b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2012 15:56:58 +0100 Subject: [PATCH] Properly recognize self as an upvar when closed over Closes #1463 --- src/comp/middle/resolve.rs | 61 +++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 664b2418d63..63a16f9b408 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -845,16 +845,14 @@ fn scope_closes(sc: scope) -> option::t { } fn def_is_local(d: def) -> bool { - ret alt d { - ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_binding(_) | - ast::def_upvar(_, _, _) { - true - } - _ { false } - }; + alt d { + ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_binding(_) | + ast::def_upvar(_, _, _) { true } + _ { false } + } } -fn def_is_obj_field(d: def) -> bool { +fn def_has_obj_scope(d: def) -> bool { alt d { ast::def_obj_field(_, _) | ast::def_self(_) { true } _ { false } @@ -947,37 +945,32 @@ fn in_scope(e: env, sp: span, name: ident, s: scope, ns: namespace) -> let fnd = in_scope(e, sp, name, hd, ns); if !is_none(fnd) { let df = option::get(fnd); - let local = def_is_local(df); - if left_fn && local || left_fn_level2 && def_is_obj_field(df) - || scope_is_fn(hd) && left_fn && def_is_ty_arg(df) { - let msg = - alt ns { - ns_type. { - "Attempt to use a type argument out of scope" - } - ns_val(v) { - alt(v) { - ns_a_tag. { - /* If we were looking for a tag, at this point - we know it's bound to a non-tag value, and - we can return none instead of failing */ - ret none; - } - _ { - "attempted dynamic environment-capture" - } - } + let local = def_is_local(df), + obj_scope = def_has_obj_scope(df); + if left_fn && local || left_fn_level2 && obj_scope + || scope_is_fn(hd) && left_fn && def_is_ty_arg(df) { + let msg = alt ns { + ns_type. { + "attempt to use a type argument out of scope" + } + ns_val(v) { + alt(v) { + /* If we were looking for a tag, at this point + we know it's bound to a non-tag value, and + we can return none instead of failing */ + ns_a_tag. { ret none; } + _ { "attempted dynamic environment-capture" } } - _ { "attempted dynamic environment-capture" } - }; + } + _ { "attempted dynamic environment-capture" } + }; e.sess.span_fatal(sp, msg); - } else if local { + } else if local || obj_scope { let i = vec::len(closing); while i > 0u { i -= 1u; - df = - ast::def_upvar(def_id_of_def(df), @df, - closing[i]); + df = ast::def_upvar(def_id_of_def(df), @df, + closing[i]); fnd = some(df); } } -- 2.44.0