diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 377863b016d85..d469191dc273b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -576,7 +576,9 @@ impl<'a, 'v> Visitor<'v> for Resolver<'a> {
                 self.visit_generics(&sig.generics);
                 MethodRibKind(!sig.decl.has_self())
             }
-            FnKind::Closure => ClosureRibKind(node_id),
+            FnKind::Closure => {
+                ClosureRibKind(node_id)
+            }
         };
         self.resolve_function(rib_kind, declaration, block);
     }
@@ -1617,6 +1619,8 @@ impl<'a> Resolver<'a> {
                         this.visit_generics(generics);
                         walk_list!(this, visit_ty_param_bound, bounds);
 
+                        let mut types = Vec::new();
+                        let mut methods = Vec::new();
                         for trait_item in trait_items {
                             match trait_item.node {
                                 TraitItemKind::Const(_, ref default) => {
@@ -1631,6 +1635,12 @@ impl<'a> Resolver<'a> {
                                         visit::walk_trait_item(this, trait_item)
                                     }
                                 }
+                                TraitItemKind::Type(..) => {
+                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
+                                        visit::walk_trait_item(this, trait_item)
+                                    });
+                                    types.push(format!("{}", trait_item.ident));
+                                }
                                 TraitItemKind::Method(ref sig, _) => {
                                     let type_parameters =
                                         HasTypeParameters(&sig.generics,
@@ -1639,14 +1649,38 @@ impl<'a> Resolver<'a> {
                                     this.with_type_parameter_rib(type_parameters, |this| {
                                         visit::walk_trait_item(this, trait_item)
                                     });
-                                }
-                                TraitItemKind::Type(..) => {
-                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
-                                        visit::walk_trait_item(this, trait_item)
-                                    });
+                                    methods.push(sig.clone());
                                 }
                             };
                         }
+                        if types.len() > 0 {
+                            for method in methods {
+                                for arg in method.decl.inputs.iter() {
+                                    if let Some(paths) = arg.ty.get_path() {
+                                        for path in paths {
+                                            if path.segments.len() == 2 &&
+                                               &format!("{}",
+                                                        path.segments[0].identifier) == "Self" {
+                                                let name = format!("{}",
+                                                                   path.segments[1].identifier);
+                                                let mut found = false;
+                                                for ty in types.iter() {
+                                                    if ty == &name {
+                                                        found = true;
+                                                        break;
+                                                    }
+                                                }
+                                                if found == false {
+                                                    let error_variant =
+                                                        ResolutionError::UndeclaredAssociatedType;
+                                                    resolve_error(this, arg.ty.span, error_variant);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     });
                 });
             }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8537fcc221c95..c3138ea6b5a3b 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1578,6 +1578,32 @@ impl fmt::Debug for Ty {
     }
 }
 
+impl Ty {
+    pub fn get_path(&self) -> Option<Vec<Path>> {
+        match self.node {
+            TyKind::Vec(ref p) | TyKind::FixedLengthVec(ref p, _) => p.get_path(),
+            TyKind::Ptr(ref p) | TyKind::Rptr(_, ref p) => p.ty.get_path(),
+            TyKind::Tup(ref v) => {
+                let mut res = Vec::new();
+                for path in v {
+                    if let Some(p) = path.get_path() {
+                        for path in p {
+                            res.push(path);
+                        }
+                    }
+                }
+                if res.len() > 0 {
+                    Some(res)
+                } else {
+                    None
+                }
+            }
+            TyKind::Path(_, ref p) => Some(vec!(p.clone())),
+            _ => None,
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
diff --git a/src/test/compile-fail/E0406.rs b/src/test/compile-fail/E0406.rs
new file mode 100644
index 0000000000000..66f82f2c1a821
--- /dev/null
+++ b/src/test/compile-fail/E0406.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+trait Foo {
+    type Bar;
+    type Bar2;
+
+    fn return_bool(&self, &Self::Bar, &Self::Baz) -> bool;
+    //~^ ERROR E0406
+    //~| ERROR E0220
+    fn return_bool2(&self, &(u32, Self::Babar)) -> bool;
+    //~^ ERROR E0406
+    //~| ERROR E0220
+}
+
+fn main() {}