about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/resolve.rs45
-rw-r--r--src/librustc/middle/typeck/check/mod.rs3
-rw-r--r--src/test/compile-fail/issue-3907-2.rs20
-rw-r--r--src/test/compile-fail/issue-3907.rs5
-rw-r--r--src/test/compile-fail/issue-3973.rs17
-rw-r--r--src/test/compile-fail/issue-5035-2.rs14
-rw-r--r--src/test/compile-fail/issue-5035.rs3
7 files changed, 94 insertions, 13 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5ce63b94b24..ee6c5e1f9bc 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -3894,8 +3894,31 @@ impl<'a> Resolver<'a> {
                 self.resolve_error(trait_reference.path.span, msg.as_slice());
             }
             Some(def) => {
-                debug!("(resolving trait) found trait def: {:?}", def);
-                self.record_def(trait_reference.ref_id, def);
+                match def {
+                    (DefTrait(_), _) => {
+                        debug!("(resolving trait) found trait def: {:?}", def);
+                        self.record_def(trait_reference.ref_id, def);
+                    }
+                    (def, _) => {
+                        self.resolve_error(trait_reference.path.span,
+                                           format!("`{}` is not a trait",
+                                                   self.path_idents_to_str(
+                                                        &trait_reference.path)));
+
+                        // If it's a typedef, give a note
+                        match def {
+                            DefTy(_) => {
+                                self.session.span_note(
+                                                trait_reference.path.span,
+                                                format!("`type` aliases cannot \
+                                                        be used for traits")
+                                                        .as_slice());
+                            }
+                            _ => {}
+                        }
+                    }
+                }
+
             }
         }
     }
@@ -4021,6 +4044,9 @@ impl<'a> Resolver<'a> {
 
                 this.with_current_self_type(self_type, |this| {
                     for method in methods.iter() {
+                        // If this is a trait impl, ensure the method exists in trait
+                        this.check_trait_method(&**method);
+
                         // We also need a new scope for the method-specific type parameters.
                         this.resolve_method(MethodRibKind(id, Provided(method.id)),
                                             &**method);
@@ -4030,6 +4056,21 @@ impl<'a> Resolver<'a> {
         });
     }
 
+    fn check_trait_method(&self, method: &Method) {
+        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
+        for &(did, ref trait_ref) in self.current_trait_ref.iter() {
+            let method_name = method.ident.name;
+
+            if self.method_map.borrow().find(&(method_name, did)).is_none() {
+                let path_str = self.path_idents_to_str(&trait_ref.path);
+                self.resolve_error(method.span,
+                                    format!("method `{}` is not a member of trait `{}`",
+                                            token::get_name(method_name),
+                                            path_str).as_slice());
+            }
+        }
+    }
+
     fn resolve_module(&mut self, module: &Mod, _span: Span,
                       _name: Ident, id: NodeId) {
         // Write the implementations in scope into the module metadata.
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 1c5cfc45afd..04db13feff6 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -784,7 +784,8 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                                     &impl_trait_ref.substs);
             }
             None => {
-                tcx.sess.span_err(
+                // This is span_bug as it should have already been caught in resolve.
+                tcx.sess.span_bug(
                     impl_method.span,
                     format!(
                         "method `{}` is not a member of trait `{}`",
diff --git a/src/test/compile-fail/issue-3907-2.rs b/src/test/compile-fail/issue-3907-2.rs
new file mode 100644
index 00000000000..795e48cb7b0
--- /dev/null
+++ b/src/test/compile-fail/issue-3907-2.rs
@@ -0,0 +1,20 @@
+// Copyright 2013-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.
+
+// aux-build:issue_3907.rs
+extern crate issue_3907;
+
+type Foo = issue_3907::Foo; //~ ERROR: reference to trait
+
+struct S {
+    name: int
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-3907.rs b/src/test/compile-fail/issue-3907.rs
index 767e674fcda..a2faef59fd8 100644
--- a/src/test/compile-fail/issue-3907.rs
+++ b/src/test/compile-fail/issue-3907.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -11,13 +11,14 @@
 // aux-build:issue_3907.rs
 extern crate issue_3907;
 
-type Foo = issue_3907::Foo; //~ ERROR: reference to trait
+type Foo = issue_3907::Foo;
 
 struct S {
     name: int
 }
 
 impl Foo for S { //~ ERROR: `Foo` is not a trait
+    //~^ NOTE: `type` aliases cannot be used for traits
     fn bar() { }
 }
 
diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs
index 7fe7778c1a5..9b77d62a065 100644
--- a/src/test/compile-fail/issue-3973.rs
+++ b/src/test/compile-fail/issue-3973.rs
@@ -8,26 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test
-
-use std::io;
-
 struct Point {
     x: f64,
     y: f64,
 }
 
-impl ToStr for Point { //~ ERROR implements a method not defined in the trait
+trait NewTrait {
+    fn a(&self) -> String;
+}
+
+impl NewTrait for Point {
     fn new(x: f64, y: f64) -> Point {
+    //~^ ERROR method `new` is not a member of trait `NewTrait`
         Point { x: x, y: y }
     }
 
-    fn to_str(&self) -> String {
+    fn a(&self) -> String {
         format!("({}, {})", self.x, self.y)
     }
 }
 
 fn main() {
     let p = Point::new(0.0, 0.0);
-    println!("{}", p.to_str());
+    //~^ ERROR unresolved name `Point::new`
+    //~^^ ERROR failed to resolve. Use of undeclared module `Point`
+    println!("{}", p.a());
 }
diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs
new file mode 100644
index 00000000000..8d9116da81d
--- /dev/null
+++ b/src/test/compile-fail/issue-5035-2.rs
@@ -0,0 +1,14 @@
+// Copyright 2013-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.
+
+trait I {}
+type K = I; //~ ERROR: reference to trait
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-5035.rs b/src/test/compile-fail/issue-5035.rs
index 94110f07762..8ffe308a669 100644
--- a/src/test/compile-fail/issue-5035.rs
+++ b/src/test/compile-fail/issue-5035.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 trait I {}
-type K = I; //~ ERROR: reference to trait
+type K = I;
 impl K for int {} //~ ERROR: `K` is not a trait
+//~^ NOTE: `type` aliases cannot be used for traits
 fn main() {}