about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs33
-rw-r--r--src/test/run-make/missing-items/Makefile10
-rw-r--r--src/test/run-make/missing-items/m1.rs17
-rw-r--r--src/test/run-make/missing-items/m2.rs19
-rw-r--r--src/test/ui/span/E0046.rs (renamed from src/test/compile-fail/E0046.rs)1
-rw-r--r--src/test/ui/span/E0046.stderr11
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.rs (renamed from src/test/compile-fail/impl-wrong-item-for-trait.rs)9
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.stderr64
-rw-r--r--src/test/ui/span/issue-23729.rs (renamed from src/test/compile-fail/issue-23729.rs)1
-rw-r--r--src/test/ui/span/issue-23729.stderr10
-rw-r--r--src/test/ui/span/issue-23827.rs (renamed from src/test/compile-fail/issue-23827.rs)1
-rw-r--r--src/test/ui/span/issue-23827.stderr10
-rw-r--r--src/test/ui/span/issue-24356.rs (renamed from src/test/compile-fail/issue-24356.rs)1
-rw-r--r--src/test/ui/span/issue-24356.stderr10
14 files changed, 186 insertions, 11 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 75a14bb3db9..d1cf3eb53a4 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1114,7 +1114,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         if !is_implemented {
             if !is_provided {
-                missing_items.push(trait_item.name());
+                missing_items.push(trait_item);
             } else if associated_type_overridden {
                 invalidated_items.push(trait_item.name());
             }
@@ -1122,16 +1122,25 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 
     if !missing_items.is_empty() {
-        struct_span_err!(tcx.sess, impl_span, E0046,
+        let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
             "not all trait items implemented, missing: `{}`",
             missing_items.iter()
-                  .map(|name| name.to_string())
-                  .collect::<Vec<_>>().join("`, `"))
-            .span_label(impl_span, &format!("missing `{}` in implementation",
+                  .map(|trait_item| trait_item.name().to_string())
+                  .collect::<Vec<_>>().join("`, `"));
+        err.span_label(impl_span, &format!("missing `{}` in implementation",
                 missing_items.iter()
-                    .map(|name| name.to_string())
-                    .collect::<Vec<_>>().join("`, `"))
-            ).emit();
+                    .map(|trait_item| trait_item.name().to_string())
+                    .collect::<Vec<_>>().join("`, `")));
+        for trait_item in missing_items {
+            if let Some(span) = tcx.map.span_if_local(trait_item.def_id()) {
+                err.span_label(span, &format!("`{}` from trait", trait_item.name()));
+            } else {
+                err.note(&format!("`{}` from trait: `{}`",
+                                  trait_item.name(),
+                                  signature(trait_item)));
+            }
+        }
+        err.emit();
     }
 
     if !invalidated_items.is_empty() {
@@ -1146,6 +1155,14 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 }
 
+fn signature<'a, 'tcx>(item: &ty::ImplOrTraitItem) -> String {
+    match *item {
+        ty::MethodTraitItem(ref item) => format!("{}", item.fty.sig.0),
+        ty::TypeTraitItem(ref item) => format!("type {};", item.name.to_string()),
+        ty::ConstTraitItem(ref item) => format!("const {}: {:?};", item.name.to_string(), item.ty),
+    }
+}
+
 /// Checks a constant with a given type.
 fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
                                    expr: &'tcx hir::Expr,
diff --git a/src/test/run-make/missing-items/Makefile b/src/test/run-make/missing-items/Makefile
new file mode 100644
index 00000000000..bcc9cdf2d65
--- /dev/null
+++ b/src/test/run-make/missing-items/Makefile
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) m1.rs -C prefer-dynamic
+	$(RUSTC) m2.rs 2>&1 | grep "error\[E0046\]: not all trait items implemented, missing: .*"
+	$(RUSTC) m2.rs 2>&1 | grep "  --> m2.rs:18:1"
+	$(RUSTC) m2.rs 2>&1 | grep "   | ^ missing .CONSTANT., .Type., .method. in implementation"
+	$(RUSTC) m2.rs 2>&1 | grep "   = note: .CONSTANT. from trait: .const CONSTANT: u32;."
+	$(RUSTC) m2.rs 2>&1 | grep "   = note: .Type. from trait: .type Type;."
+	$(RUSTC) m2.rs 2>&1 | grep "   = note: .method. from trait: .fn(&Self, std::string::String) -> <Self as m1::X>::Type."
diff --git a/src/test/run-make/missing-items/m1.rs b/src/test/run-make/missing-items/m1.rs
new file mode 100644
index 00000000000..060c7a9571b
--- /dev/null
+++ b/src/test/run-make/missing-items/m1.rs
@@ -0,0 +1,17 @@
+// 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.
+
+#![feature(associated_consts)]
+#![crate_type = "dylib"]
+pub trait X {
+  const CONSTANT: u32;
+  type Type;
+  fn method(&self, s: String) -> Self::Type;
+}
diff --git a/src/test/run-make/missing-items/m2.rs b/src/test/run-make/missing-items/m2.rs
new file mode 100644
index 00000000000..7055673acc9
--- /dev/null
+++ b/src/test/run-make/missing-items/m2.rs
@@ -0,0 +1,19 @@
+// 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.
+
+#![feature(associated_consts)]
+#![crate_type = "dylib"]
+extern crate m1;
+
+struct X {
+}
+
+impl m1::X for X {
+}
diff --git a/src/test/compile-fail/E0046.rs b/src/test/ui/span/E0046.rs
index a8b56b2b9ab..9e757860a85 100644
--- a/src/test/compile-fail/E0046.rs
+++ b/src/test/ui/span/E0046.rs
@@ -10,6 +10,7 @@
 
 trait Foo {
     fn foo();
+    //~^ NOTE `foo` from trait
 }
 
 struct Bar;
diff --git a/src/test/ui/span/E0046.stderr b/src/test/ui/span/E0046.stderr
new file mode 100644
index 00000000000..729a5156124
--- /dev/null
+++ b/src/test/ui/span/E0046.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/E0046.rs:18:1
+   |
+12 |     fn foo();
+   |     --------- `foo` from trait
+...
+18 | impl Foo for Bar {}
+   | ^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/impl-wrong-item-for-trait.rs b/src/test/ui/span/impl-wrong-item-for-trait.rs
index 388c9a1729c..54ed42af5d5 100644
--- a/src/test/compile-fail/impl-wrong-item-for-trait.rs
+++ b/src/test/ui/span/impl-wrong-item-for-trait.rs
@@ -10,11 +10,11 @@
 
 #![feature(associated_consts)]
 
+use std::fmt::Debug;
+
 trait Foo {
     fn bar(&self);
-    //~^ NOTE item in trait
-    //~| NOTE item in trait
-    const MY_CONST: u32; //~ NOTE item in trait
+    const MY_CONST: u32;
 }
 
 pub struct FooConstForMethod;
@@ -50,4 +50,7 @@ impl Foo for FooTypeForMethod {
     const MY_CONST: u32 = 1;
 }
 
+impl Debug for FooTypeForMethod {
+}
+
 fn main () {}
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
new file mode 100644
index 00000000000..244285e3584
--- /dev/null
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -0,0 +1,64 @@
+error[E0323]: item `bar` is an associated const, which doesn't match its trait `<FooConstForMethod as Foo>`
+  --> $DIR/impl-wrong-item-for-trait.rs:25:5
+   |
+16 |     fn bar(&self);
+   |     -------------- item in trait
+...
+25 |     const bar: u64 = 1;
+   |     ^^^^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0046]: not all trait items implemented, missing: `bar`
+  --> $DIR/impl-wrong-item-for-trait.rs:22:1
+   |
+16 |     fn bar(&self);
+   |     -------------- `bar` from trait
+...
+22 | impl Foo for FooConstForMethod {
+   | ^ missing `bar` in implementation
+
+error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `<FooMethodForConst as Foo>`
+  --> $DIR/impl-wrong-item-for-trait.rs:37:5
+   |
+17 |     const MY_CONST: u32;
+   |     -------------------- item in trait
+...
+37 |     fn MY_CONST() {}
+   |     ^^^^^^^^^^^^^^^^ does not match trait
+
+error[E0046]: not all trait items implemented, missing: `MY_CONST`
+  --> $DIR/impl-wrong-item-for-trait.rs:33:1
+   |
+17 |     const MY_CONST: u32;
+   |     -------------------- `MY_CONST` from trait
+...
+33 | impl Foo for FooMethodForConst {
+   | ^ missing `MY_CONST` in implementation
+
+error[E0325]: item `bar` is an associated type, which doesn't match its trait `<FooTypeForMethod as Foo>`
+  --> $DIR/impl-wrong-item-for-trait.rs:47:5
+   |
+16 |     fn bar(&self);
+   |     -------------- item in trait
+...
+47 |     type bar = u64;
+   |     ^^^^^^^^^^^^^^^ does not match trait
+
+error[E0046]: not all trait items implemented, missing: `bar`
+  --> $DIR/impl-wrong-item-for-trait.rs:44:1
+   |
+16 |     fn bar(&self);
+   |     -------------- `bar` from trait
+...
+44 | impl Foo for FooTypeForMethod {
+   | ^ missing `bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `fmt`
+  --> $DIR/impl-wrong-item-for-trait.rs:53:1
+   |
+53 | impl Debug for FooTypeForMethod {
+   | ^ missing `fmt` in implementation
+   |
+   = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/test/compile-fail/issue-23729.rs b/src/test/ui/span/issue-23729.rs
index b1047ce18cc..66134a03baf 100644
--- a/src/test/compile-fail/issue-23729.rs
+++ b/src/test/ui/span/issue-23729.rs
@@ -20,6 +20,7 @@ fn main() {
         impl Iterator for Recurrence {
             //~^ ERROR E0046
             //~| NOTE missing `Item` in implementation
+            //~| NOTE `Item` from trait: `type Item;`
             #[inline]
             fn next(&mut self) -> Option<u64> {
                 if self.pos < 2 {
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
new file mode 100644
index 00000000000..493ca01778b
--- /dev/null
+++ b/src/test/ui/span/issue-23729.stderr
@@ -0,0 +1,10 @@
+error[E0046]: not all trait items implemented, missing: `Item`
+  --> $DIR/issue-23729.rs:20:9
+   |
+20 |         impl Iterator for Recurrence {
+   |         ^ missing `Item` in implementation
+   |
+   = note: `Item` from trait: `type Item;`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/issue-23827.rs b/src/test/ui/span/issue-23827.rs
index 2062e237312..a5ab443597b 100644
--- a/src/test/compile-fail/issue-23827.rs
+++ b/src/test/ui/span/issue-23827.rs
@@ -36,6 +36,7 @@ impl<C: Component> FnMut<(C,)> for Prototype {
 impl<C: Component> FnOnce<(C,)> for Prototype {
     //~^ ERROR E0046
     //~| NOTE missing `Output` in implementation
+    //~| NOTE `Output` from trait: `type Output;`
     extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype {
         Fn::call(&self, (comp,))
     }
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
new file mode 100644
index 00000000000..5130bb53a19
--- /dev/null
+++ b/src/test/ui/span/issue-23827.stderr
@@ -0,0 +1,10 @@
+error[E0046]: not all trait items implemented, missing: `Output`
+  --> $DIR/issue-23827.rs:36:1
+   |
+36 | impl<C: Component> FnOnce<(C,)> for Prototype {
+   | ^ missing `Output` in implementation
+   |
+   = note: `Output` from trait: `type Output;`
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/issue-24356.rs b/src/test/ui/span/issue-24356.rs
index d39fd539dce..0997dc802f8 100644
--- a/src/test/compile-fail/issue-24356.rs
+++ b/src/test/ui/span/issue-24356.rs
@@ -30,6 +30,7 @@ fn main() {
         impl Deref for Thing {
             //~^ ERROR E0046
             //~| NOTE missing `Target` in implementation
+            //~| NOTE `Target` from trait: `type Target;`
             fn deref(&self) -> i8 { self.0 }
         }
 
diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr
new file mode 100644
index 00000000000..906ef25ca0e
--- /dev/null
+++ b/src/test/ui/span/issue-24356.stderr
@@ -0,0 +1,10 @@
+error[E0046]: not all trait items implemented, missing: `Target`
+  --> $DIR/issue-24356.rs:30:9
+   |
+30 |         impl Deref for Thing {
+   |         ^ missing `Target` in implementation
+   |
+   = note: `Target` from trait: `type Target;`
+
+error: aborting due to previous error
+