Skip to content

Commit 1414e89

Browse files
E0406 is now thrown like expected
1 parent 646015c commit 1414e89

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

src/librustc_resolve/lib.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,9 @@ impl<'a, 'v> Visitor<'v> for Resolver<'a> {
576576
self.visit_generics(&sig.generics);
577577
MethodRibKind(!sig.decl.has_self())
578578
}
579-
FnKind::Closure => ClosureRibKind(node_id),
579+
FnKind::Closure => {
580+
ClosureRibKind(node_id)
581+
}
580582
};
581583
self.resolve_function(rib_kind, declaration, block);
582584
}
@@ -1617,6 +1619,8 @@ impl<'a> Resolver<'a> {
16171619
this.visit_generics(generics);
16181620
walk_list!(this, visit_ty_param_bound, bounds);
16191621

1622+
let mut types = Vec::new();
1623+
let mut methods = Vec::new();
16201624
for trait_item in trait_items {
16211625
match trait_item.node {
16221626
TraitItemKind::Const(_, ref default) => {
@@ -1631,6 +1635,12 @@ impl<'a> Resolver<'a> {
16311635
visit::walk_trait_item(this, trait_item)
16321636
}
16331637
}
1638+
TraitItemKind::Type(..) => {
1639+
this.with_type_parameter_rib(NoTypeParameters, |this| {
1640+
visit::walk_trait_item(this, trait_item)
1641+
});
1642+
types.push(format!("{}", trait_item.ident));
1643+
}
16341644
TraitItemKind::Method(ref sig, _) => {
16351645
let type_parameters =
16361646
HasTypeParameters(&sig.generics,
@@ -1639,14 +1649,38 @@ impl<'a> Resolver<'a> {
16391649
this.with_type_parameter_rib(type_parameters, |this| {
16401650
visit::walk_trait_item(this, trait_item)
16411651
});
1642-
}
1643-
TraitItemKind::Type(..) => {
1644-
this.with_type_parameter_rib(NoTypeParameters, |this| {
1645-
visit::walk_trait_item(this, trait_item)
1646-
});
1652+
methods.push(sig.clone());
16471653
}
16481654
};
16491655
}
1656+
if types.len() > 0 {
1657+
for method in methods {
1658+
for arg in method.decl.inputs.iter() {
1659+
if let Some(paths) = arg.ty.get_path() {
1660+
for path in paths {
1661+
if path.segments.len() == 2 &&
1662+
&format!("{}",
1663+
path.segments[0].identifier) == "Self" {
1664+
let name = format!("{}",
1665+
path.segments[1].identifier);
1666+
let mut found = false;
1667+
for ty in types.iter() {
1668+
if ty == &name {
1669+
found = true;
1670+
break;
1671+
}
1672+
}
1673+
if found == false {
1674+
let error_variant =
1675+
ResolutionError::UndeclaredAssociatedType;
1676+
resolve_error(this, arg.ty.span, error_variant);
1677+
}
1678+
}
1679+
}
1680+
}
1681+
}
1682+
}
1683+
}
16501684
});
16511685
});
16521686
}

src/libsyntax/ast.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,32 @@ impl fmt::Debug for Ty {
15781578
}
15791579
}
15801580

1581+
impl Ty {
1582+
pub fn get_path(&self) -> Option<Vec<Path>> {
1583+
match self.node {
1584+
TyKind::Vec(ref p) | TyKind::FixedLengthVec(ref p, _) => p.get_path(),
1585+
TyKind::Ptr(ref p) | TyKind::Rptr(_, ref p) => p.ty.get_path(),
1586+
TyKind::Tup(ref v) => {
1587+
let mut res = Vec::new();
1588+
for path in v {
1589+
if let Some(p) = path.get_path() {
1590+
for path in p {
1591+
res.push(path);
1592+
}
1593+
}
1594+
}
1595+
if res.len() > 0 {
1596+
Some(res)
1597+
} else {
1598+
None
1599+
}
1600+
}
1601+
TyKind::Path(_, ref p) => Some(vec!(p.clone())),
1602+
_ => None,
1603+
}
1604+
}
1605+
}
1606+
15811607
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
15821608
pub struct BareFnTy {
15831609
pub unsafety: Unsafety,

src/test/compile-fail/E0406.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 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+
trait Foo {
12+
type Bar;
13+
type Bar2;
14+
15+
fn return_bool(&self, &Self::Bar, &Self::Baz) -> bool;
16+
//~^ ERROR E0406
17+
//~| ERROR E0220
18+
fn return_bool2(&self, &(u32, Self::Babar)) -> bool;
19+
//~^ ERROR E0406
20+
//~| ERROR E0220
21+
}
22+
23+
fn main() {}

0 commit comments

Comments
 (0)