Skip to content

Commit c13f087

Browse files
committed
Properly recognize self as an upvar when closed over
Closes #1463
1 parent 51364b5 commit c13f087

File tree

1 file changed

+27
-34
lines changed

1 file changed

+27
-34
lines changed

src/comp/middle/resolve.rs

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -845,16 +845,14 @@ fn scope_closes(sc: scope) -> option::t<node_id> {
845845
}
846846

847847
fn def_is_local(d: def) -> bool {
848-
ret alt d {
849-
ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_binding(_) |
850-
ast::def_upvar(_, _, _) {
851-
true
852-
}
853-
_ { false }
854-
};
848+
alt d {
849+
ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_binding(_) |
850+
ast::def_upvar(_, _, _) { true }
851+
_ { false }
852+
}
855853
}
856854

857-
fn def_is_obj_field(d: def) -> bool {
855+
fn def_has_obj_scope(d: def) -> bool {
858856
alt d {
859857
ast::def_obj_field(_, _) | ast::def_self(_) { true }
860858
_ { false }
@@ -947,37 +945,32 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
947945
let fnd = in_scope(e, sp, name, hd, ns);
948946
if !is_none(fnd) {
949947
let df = option::get(fnd);
950-
let local = def_is_local(df);
951-
if left_fn && local || left_fn_level2 && def_is_obj_field(df)
952-
|| scope_is_fn(hd) && left_fn && def_is_ty_arg(df) {
953-
let msg =
954-
alt ns {
955-
ns_type. {
956-
"Attempt to use a type argument out of scope"
957-
}
958-
ns_val(v) {
959-
alt(v) {
960-
ns_a_tag. {
961-
/* If we were looking for a tag, at this point
962-
we know it's bound to a non-tag value, and
963-
we can return none instead of failing */
964-
ret none;
965-
}
966-
_ {
967-
"attempted dynamic environment-capture"
968-
}
969-
}
948+
let local = def_is_local(df),
949+
obj_scope = def_has_obj_scope(df);
950+
if left_fn && local || left_fn_level2 && obj_scope
951+
|| scope_is_fn(hd) && left_fn && def_is_ty_arg(df) {
952+
let msg = alt ns {
953+
ns_type. {
954+
"attempt to use a type argument out of scope"
955+
}
956+
ns_val(v) {
957+
alt(v) {
958+
/* If we were looking for a tag, at this point
959+
we know it's bound to a non-tag value, and
960+
we can return none instead of failing */
961+
ns_a_tag. { ret none; }
962+
_ { "attempted dynamic environment-capture" }
970963
}
971-
_ { "attempted dynamic environment-capture" }
972-
};
964+
}
965+
_ { "attempted dynamic environment-capture" }
966+
};
973967
e.sess.span_fatal(sp, msg);
974-
} else if local {
968+
} else if local || obj_scope {
975969
let i = vec::len(closing);
976970
while i > 0u {
977971
i -= 1u;
978-
df =
979-
ast::def_upvar(def_id_of_def(df), @df,
980-
closing[i]);
972+
df = ast::def_upvar(def_id_of_def(df), @df,
973+
closing[i]);
981974
fnd = some(df);
982975
}
983976
}

0 commit comments

Comments
 (0)