]> git.lizzy.rs Git - rust.git/commitdiff
Make resolve check for type-variable name-shadowing
authorTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 12 Jul 2011 20:42:05 +0000 (13:42 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 12 Jul 2011 20:42:05 +0000 (13:42 -0700)
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
src/test/compile-fail/nested-ty-params.rs
src/test/compile-fail/type-arg-out-of-scope.rs [new file with mode: 0644]

index 6fb22c34d199022d1392c5699d9a7a2eac4a6ea3..080d9270f6adaf0877110e8d8d59c9a56c657526 100644 (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 in_scope(&env e, &span sp, &ident name, &scope s, 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;
             }
         }
index e4fed7f07ec86c82461d8b77023bd6537acf4aa0..bbb246ea1dc479937526c14fc1995b474c9cb07e 100644 (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);
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 (file)
index 0000000..46f3655
--- /dev/null
@@ -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); }