From f7a1006a07b396ed239c08d3576597dad103e064 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 12 Jul 2011 13:42:05 -0700 Subject: [PATCH] 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. --- src/comp/middle/resolve.rs | 23 +++++++++++++++---- src/test/compile-fail/nested-ty-params.rs | 7 ++---- .../compile-fail/type-arg-out-of-scope.rs | 6 +++++ 3 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 src/test/compile-fail/type-arg-out-of-scope.rs diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 6fb22c34d199..080d9270f6ad 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -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; } } diff --git a/src/test/compile-fail/nested-ty-params.rs b/src/test/compile-fail/nested-ty-params.rs index e4fed7f07ec8..bbb246ea1dc4 100644 --- a/src/test/compile-fail/nested-ty-params.rs +++ b/src/test/compile-fail/nested-ty-params.rs @@ -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); diff --git a/src/test/compile-fail/type-arg-out-of-scope.rs b/src/test/compile-fail/type-arg-out-of-scope.rs new file mode 100644 index 000000000000..46f365537dfb --- /dev/null +++ b/src/test/compile-fail/type-arg-out-of-scope.rs @@ -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); }