Skip to content

Commit

Permalink
Fix resolve to not permit refs to type vars from outer fns
Browse files Browse the repository at this point in the history
(Fixes #14603)
  • Loading branch information
nikomatsakis committed Jun 6, 2014
1 parent 3fecd10 commit 4a51e9c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 16 deletions.
33 changes: 21 additions & 12 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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, ());
});
Expand All @@ -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, ());
});
Expand All @@ -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()
Expand Down Expand Up @@ -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,
()));
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
};

Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-12796.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-5997-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
49 changes: 49 additions & 0 deletions src/test/compile-fail/resolve-type-param-in-item-in-trait.rs
Original file line number Diff line number Diff line change
@@ -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() { }

5 comments on commit 4a51e9c

@bors
Copy link
Contributor

@bors bors commented on 4a51e9c Jun 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from pnkfelix
at nikomatsakis@4a51e9c

@bors
Copy link
Contributor

@bors bors commented on 4a51e9c Jun 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging nikomatsakis/rust/issue-5527-namespace-substs-b = 4a51e9c into auto

@bors
Copy link
Contributor

@bors bors commented on 4a51e9c Jun 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nikomatsakis/rust/issue-5527-namespace-substs-b = 4a51e9c merged ok, testing candidate = bd6683c

@bors
Copy link
Contributor

@bors bors commented on 4a51e9c Jun 7, 2014

@bors
Copy link
Contributor

@bors bors commented on 4a51e9c Jun 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = bd6683c

Please sign in to comment.