about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-05-31 01:54:04 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-06-06 19:51:24 -0400
commit4a51e9c5493ff80d3783a51d130a87a08b8de74d (patch)
treee761b846e420c33979c1a89d5008352fd997267e
parent3fecd10428bbefd162a75512acb807dd65dcb1dd (diff)
downloadrust-4a51e9c5493ff80d3783a51d130a87a08b8de74d.tar.gz
rust-4a51e9c5493ff80d3783a51d130a87a08b8de74d.zip
Fix resolve to not permit refs to type vars from outer fns
(Fixes #14603)
-rw-r--r--src/librustc/middle/resolve.rs33
-rw-r--r--src/test/compile-fail/issue-12796.rs4
-rw-r--r--src/test/compile-fail/issue-5997-enum.rs4
-rw-r--r--src/test/compile-fail/resolve-type-param-in-item-in-trait.rs49
4 files changed, 74 insertions, 16 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index f4962c9083a..9bfa0e10aed 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -266,8 +266,8 @@ enum RibKind {
               // parent;   method itself
     MethodRibKind(NodeId, MethodSort),
 
-    // We passed through a function *item* scope. Disallow upvars.
-    OpaqueFunctionRibKind,
+    // We passed through an item scope. Disallow upvars.
+    ItemRibKind,
 
     // We're in a constant item. Can't refer to dynamic stuff.
     ConstantItemRibKind
@@ -3418,7 +3418,8 @@ impl<'a> Resolver<'a> {
                 def = d;
                 is_ty_param = false;
             }
-            DlDef(d @ DefTyParam(..)) => {
+            DlDef(d @ DefTyParam(..)) |
+            DlDef(d @ DefSelfTy(..)) => {
                 def = d;
                 is_ty_param = true;
             }
@@ -3451,6 +3452,13 @@ impl<'a> Resolver<'a> {
                     } => {
                       // ok
                     }
+
+                    DefSelfTy(did) if {
+                        did == item_id
+                    } => {
+                      // ok
+                    }
+
                     _ => {
                     if !is_ty_param {
                         // This was an attempt to access an upvar inside a
@@ -3475,7 +3483,7 @@ impl<'a> Resolver<'a> {
                     }
                   }
                 }
-                OpaqueFunctionRibKind => {
+                ItemRibKind => {
                     if !is_ty_param {
                         // This was an attempt to access an upvar inside a
                         // named function item. This is not allowed, so we
@@ -3575,7 +3583,7 @@ impl<'a> Resolver<'a> {
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                item.id,
                                                                0,
-                                                               NormalRibKind),
+                                                               ItemRibKind),
                                              |this| {
                     visit::walk_item(this, item, ());
                 });
@@ -3585,7 +3593,7 @@ impl<'a> Resolver<'a> {
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                item.id,
                                                                0,
-                                                               NormalRibKind),
+                                                               ItemRibKind),
                                              |this| {
                     visit::walk_item(this, item, ());
                 });
@@ -3604,7 +3612,8 @@ impl<'a> Resolver<'a> {
 
             ItemTrait(ref generics, _, ref traits, ref methods) => {
                 // Create a new rib for the self type.
-                let self_type_rib = Rib::new(NormalRibKind);
+                let self_type_rib = Rib::new(ItemRibKind);
+
                 // plain insert (no renaming)
                 let name = self.type_self_ident.name;
                 self_type_rib.bindings.borrow_mut()
@@ -3686,7 +3695,7 @@ impl<'a> Resolver<'a> {
                                 this.with_type_parameter_rib(
                                     HasTypeParameters(
                                         generics, foreign_item.id, 0,
-                                        NormalRibKind),
+                                        ItemRibKind),
                                     |this| visit::walk_foreign_item(this,
                                                                 *foreign_item,
                                                                 ()));
@@ -3702,13 +3711,13 @@ impl<'a> Resolver<'a> {
             }
 
             ItemFn(fn_decl, _, _, ref generics, block) => {
-                self.resolve_function(OpaqueFunctionRibKind,
+                self.resolve_function(ItemRibKind,
                                       Some(fn_decl),
                                       HasTypeParameters
                                         (generics,
                                          item.id,
                                          0,
-                                         OpaqueFunctionRibKind),
+                                         ItemRibKind),
                                       block);
             }
 
@@ -3890,7 +3899,7 @@ impl<'a> Resolver<'a> {
         self.with_type_parameter_rib(HasTypeParameters(generics,
                                                        id,
                                                        0,
-                                                       OpaqueFunctionRibKind),
+                                                       ItemRibKind),
                                      |this| {
             // Resolve the type parameters.
             this.resolve_type_parameters(&generics.ty_params);
@@ -5119,7 +5128,7 @@ impl<'a> Resolver<'a> {
                                 self.value_ribs.borrow().iter().rev().advance(|rib| {
                                     let res = match *rib {
                                         Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
-                                        Rib { bindings: _, kind: OpaqueFunctionRibKind } => false,
+                                        Rib { bindings: _, kind: ItemRibKind } => false,
                                         _ => return true, // Keep advancing
                                     };
 
diff --git a/src/test/compile-fail/issue-12796.rs b/src/test/compile-fail/issue-12796.rs
index 8b5fb90e2d4..ce3c8c52b0e 100644
--- a/src/test/compile-fail/issue-12796.rs
+++ b/src/test/compile-fail/issue-12796.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: missing `Self` type param in the substitution of `fn(Self)`
-
 trait Trait {
     fn outer(self) {
         fn inner(_: Self) {
+            //~^ ERROR can't use type parameters from outer function
+            //~^^ ERROR use of undeclared type name `Self`
         }
     }
 }
diff --git a/src/test/compile-fail/issue-5997-enum.rs b/src/test/compile-fail/issue-5997-enum.rs
index 7be01b4abb4..39e1e117cd0 100644
--- a/src/test/compile-fail/issue-5997-enum.rs
+++ b/src/test/compile-fail/issue-5997-enum.rs
@@ -10,8 +10,8 @@
 
 fn f<Z>() -> bool {
     enum E { V(Z) }
-    //~^ ERROR can't use type parameters from outer function in the
-
+    //~^ ERROR can't use type parameters from outer function
+    //~^^ ERROR use of undeclared type name `Z`
     true
 }
 
diff --git a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
new file mode 100644
index 00000000000..341fe173a03
--- /dev/null
+++ b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
@@ -0,0 +1,49 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue #14603: Check for references to type parameters from the
+// outer scope (in this case, the trait) used on items in an inner
+// scope (in this case, the enum).
+
+trait TraitA<A> {
+    fn outer(self) {
+        enum Foo<B> {
+            Variance(A)
+                //~^ ERROR can't use type parameters from outer function
+                //~^^ ERROR use of undeclared type name `A`
+        }
+    }
+}
+
+trait TraitB<A> {
+    fn outer(self) {
+        struct Foo<B>(A);
+                //~^ ERROR can't use type parameters from outer function
+                //~^^ ERROR use of undeclared type name `A`
+    }
+}
+
+trait TraitC<A> {
+    fn outer(self) {
+        struct Foo<B> { a: A }
+                //~^ ERROR can't use type parameters from outer function
+                //~^^ ERROR use of undeclared type name `A`
+    }
+}
+
+trait TraitD<A> {
+    fn outer(self) {
+        fn foo<B>(a: A) { }
+                //~^ ERROR can't use type parameters from outer function
+                //~^^ ERROR use of undeclared type name `A`
+    }
+}
+
+fn main() { }