diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-05-31 01:54:04 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-06-06 19:51:24 -0400 |
| commit | 4a51e9c5493ff80d3783a51d130a87a08b8de74d (patch) | |
| tree | e761b846e420c33979c1a89d5008352fd997267e | |
| parent | 3fecd10428bbefd162a75512acb807dd65dcb1dd (diff) | |
| download | rust-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.rs | 33 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-12796.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-5997-enum.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/resolve-type-param-in-item-in-trait.rs | 49 |
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() { } |
