Skip to content

Commit c1b2173

Browse files
nikomatsakisalexcrichton
authored andcommitted
Fix resolve to not permit refs to type vars from outer fns
(Fixes #14603)
1 parent 408810c commit c1b2173

File tree

2 files changed

+70
-12
lines changed

2 files changed

+70
-12
lines changed

Diff for: src/librustc/middle/resolve.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ enum RibKind {
266266
// parent; method itself
267267
MethodRibKind(NodeId, MethodSort),
268268

269-
// We passed through a function *item* scope. Disallow upvars.
270-
OpaqueFunctionRibKind,
269+
// We passed through an item scope. Disallow upvars.
270+
ItemRibKind,
271271

272272
// We're in a constant item. Can't refer to dynamic stuff.
273273
ConstantItemRibKind
@@ -3418,7 +3418,8 @@ impl<'a> Resolver<'a> {
34183418
def = d;
34193419
is_ty_param = false;
34203420
}
3421-
DlDef(d @ DefTyParam(..)) => {
3421+
DlDef(d @ DefTyParam(..)) |
3422+
DlDef(d @ DefSelfTy(..)) => {
34223423
def = d;
34233424
is_ty_param = true;
34243425
}
@@ -3451,6 +3452,13 @@ impl<'a> Resolver<'a> {
34513452
} => {
34523453
// ok
34533454
}
3455+
3456+
DefSelfTy(did) if {
3457+
did == item_id
3458+
} => {
3459+
// ok
3460+
}
3461+
34543462
_ => {
34553463
if !is_ty_param {
34563464
// This was an attempt to access an upvar inside a
@@ -3475,7 +3483,7 @@ impl<'a> Resolver<'a> {
34753483
}
34763484
}
34773485
}
3478-
OpaqueFunctionRibKind => {
3486+
ItemRibKind => {
34793487
if !is_ty_param {
34803488
// This was an attempt to access an upvar inside a
34813489
// named function item. This is not allowed, so we
@@ -3575,7 +3583,7 @@ impl<'a> Resolver<'a> {
35753583
self.with_type_parameter_rib(HasTypeParameters(generics,
35763584
item.id,
35773585
0,
3578-
NormalRibKind),
3586+
ItemRibKind),
35793587
|this| {
35803588
visit::walk_item(this, item, ());
35813589
});
@@ -3585,7 +3593,7 @@ impl<'a> Resolver<'a> {
35853593
self.with_type_parameter_rib(HasTypeParameters(generics,
35863594
item.id,
35873595
0,
3588-
NormalRibKind),
3596+
ItemRibKind),
35893597
|this| {
35903598
visit::walk_item(this, item, ());
35913599
});
@@ -3604,7 +3612,8 @@ impl<'a> Resolver<'a> {
36043612

36053613
ItemTrait(ref generics, _, ref traits, ref methods) => {
36063614
// Create a new rib for the self type.
3607-
let self_type_rib = Rib::new(NormalRibKind);
3615+
let self_type_rib = Rib::new(ItemRibKind);
3616+
36083617
// plain insert (no renaming)
36093618
let name = self.type_self_ident.name;
36103619
self_type_rib.bindings.borrow_mut()
@@ -3686,7 +3695,7 @@ impl<'a> Resolver<'a> {
36863695
this.with_type_parameter_rib(
36873696
HasTypeParameters(
36883697
generics, foreign_item.id, 0,
3689-
NormalRibKind),
3698+
ItemRibKind),
36903699
|this| visit::walk_foreign_item(this,
36913700
*foreign_item,
36923701
()));
@@ -3702,13 +3711,13 @@ impl<'a> Resolver<'a> {
37023711
}
37033712

37043713
ItemFn(fn_decl, _, _, ref generics, block) => {
3705-
self.resolve_function(OpaqueFunctionRibKind,
3714+
self.resolve_function(ItemRibKind,
37063715
Some(fn_decl),
37073716
HasTypeParameters
37083717
(generics,
37093718
item.id,
37103719
0,
3711-
OpaqueFunctionRibKind),
3720+
ItemRibKind),
37123721
block);
37133722
}
37143723

@@ -3890,7 +3899,7 @@ impl<'a> Resolver<'a> {
38903899
self.with_type_parameter_rib(HasTypeParameters(generics,
38913900
id,
38923901
0,
3893-
OpaqueFunctionRibKind),
3902+
ItemRibKind),
38943903
|this| {
38953904
// Resolve the type parameters.
38963905
this.resolve_type_parameters(&generics.ty_params);
@@ -5119,7 +5128,7 @@ impl<'a> Resolver<'a> {
51195128
self.value_ribs.borrow().iter().rev().advance(|rib| {
51205129
let res = match *rib {
51215130
Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5122-
Rib { bindings: _, kind: OpaqueFunctionRibKind } => false,
5131+
Rib { bindings: _, kind: ItemRibKind } => false,
51235132
_ => return true, // Keep advancing
51245133
};
51255134

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #14603: Check for references to type parameters from the
12+
// outer scope (in this case, the trait) used on items in an inner
13+
// scope (in this case, the enum).
14+
15+
trait TraitA<A> {
16+
fn outer(self) {
17+
enum Foo<B> {
18+
Variance(A)
19+
//~^ ERROR can't use type parameters from outer function
20+
//~^^ ERROR use of undeclared type name `A`
21+
}
22+
}
23+
}
24+
25+
trait TraitB<A> {
26+
fn outer(self) {
27+
struct Foo<B>(A);
28+
//~^ ERROR can't use type parameters from outer function
29+
//~^^ ERROR use of undeclared type name `A`
30+
}
31+
}
32+
33+
trait TraitC<A> {
34+
fn outer(self) {
35+
struct Foo<B> { a: A }
36+
//~^ ERROR can't use type parameters from outer function
37+
//~^^ ERROR use of undeclared type name `A`
38+
}
39+
}
40+
41+
trait TraitD<A> {
42+
fn outer(self) {
43+
fn foo<B>(a: A) { }
44+
//~^ ERROR can't use type parameters from outer function
45+
//~^^ ERROR use of undeclared type name `A`
46+
}
47+
}
48+
49+
fn main() { }

0 commit comments

Comments
 (0)