Make resolve check for type-variable name-shadowing

Capturing a type argument in the enclosing scope should be an error --
this commit implements that check in resolve, avoiding a potential
assertion failure in trans.

Closes #648.
This commit is contained in:
Tim Chevalier 2011-07-12 13:42:05 -07:00
parent 0d9c08af2a
commit f7a1006a07
3 changed files with 26 additions and 10 deletions

View File

@ -596,6 +596,10 @@ fn def_is_obj_field(&def d) -> bool {
ret alt (d) { case (ast::def_obj_field(_)) { true } case (_) { false } };
}
fn def_is_ty_arg(&def d) -> bool {
ret alt(d) { case (ast::def_ty_arg(_)) { true } case (_) { false } };
}
fn lookup_in_scope(&env e, scopes sc, &span sp, &ident name, namespace ns) ->
option::t[def] {
fn in_scope(&env e, &span sp, &ident name, &scope s, namespace ns) ->
@ -666,15 +670,24 @@ fn lookup_in_scope(&env e, scopes sc, &span sp, &ident name, namespace ns) ->
if (!option::is_none(fnd)) {
auto df = option::get(fnd);
if (left_fn && def_is_local(df) ||
left_fn_level2 && def_is_obj_field(df)) {
e.sess.span_fatal(sp,
"attempted dynamic \
environment-capture");
left_fn_level2 && def_is_obj_field(df)
|| (scope_is_fn(hd) && left_fn
&& def_is_ty_arg(df))) {
auto msg = alt (ns) {
case (ns_type) {
"Attempt to use a type \
argument out of scope"
}
case (_) { "attempted dynamic \
environment-capture" }
};
e.sess.span_fatal(sp, msg);
}
ret fnd;
}
if (left_fn) { left_fn_level2 = true; }
if (ns == ns_value && !left_fn) { left_fn = scope_is_fn(hd); }
if ((ns == ns_value || ns == ns_type) && !left_fn) {
left_fn = scope_is_fn(hd); }
sc = *tl;
}
}

View File

@ -1,8 +1,5 @@
// error-pattern:Unbound type parameter in callee
/* I'm actually not sure whether this should compile.
But having a nice error message seems better than
a bounds check failure (which is what was happening
before.) */
// xfail-stage0
// error-pattern:Attempt to use a type argument out of scope
fn hd[U](&vec[U] v) -> U {
fn hd1(&vec[U] w) -> U {
ret w.(0);

View File

@ -0,0 +1,6 @@
// xfail-stage0
// error-pattern:Attempt to use a type argument out of scope
fn foo[T] (&T x) {
fn bar(fn (&T) -> T f) { };
}
fn main() { foo(1); }