about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2016-09-10 15:27:33 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2016-09-28 11:39:55 +0200
commit61cbf414d7f4ea19de66da25d0ea034541e31750 (patch)
treedb3327b5580fafe9326069c0c15d0f79d768d147
parentbdad70213b32454837c0ed16dbbac3954325feea (diff)
downloadrust-61cbf414d7f4ea19de66da25d0ea034541e31750.tar.gz
rust-61cbf414d7f4ea19de66da25d0ea034541e31750.zip
Update E0050 to new error format
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc_typeck/check/compare_method.rs64
-rw-r--r--src/test/compile-fail/E0050.rs9
3 files changed, 69 insertions, 6 deletions
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index b351bd427ac..b2ae0b7b609 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -260,7 +260,7 @@ impl<'ast> Map<'ast> {
                     EntryVariant(p, _) |
                     EntryExpr(p, _) |
                     EntryStmt(p, _) |
-                EntryTy(p, _) |
+                    EntryTy(p, _) |
                     EntryLocal(p, _) |
                     EntryPat(p, _) |
                     EntryBlock(p, _) |
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 4a631493398..b44ff5ce07e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -138,14 +138,70 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 
     if impl_m.fty.sig.0.inputs.len() != trait_m.fty.sig.0.inputs.len() {
-        span_err!(tcx.sess, impl_m_span, E0050,
+        let trait_number_args = trait_m.fty.sig.0.inputs.len();
+        let impl_number_args = impl_m.fty.sig.0.inputs.len();
+        let trait_m_node_id = tcx.map.as_local_node_id(trait_m.def_id);
+        let trait_span = if let Some(trait_id) = trait_m_node_id {
+            match tcx.map.expect_trait_item(trait_id).node {
+                TraitItem_::MethodTraitItem(ref trait_m_sig, _) => {
+                    if let Some(arg) = trait_m_sig.decl.inputs.get(
+                        if trait_number_args > 0 {
+                            trait_number_args - 1
+                        } else {
+                            0
+                        }) {
+                        Some(arg.pat.span)
+                    } else {
+                        trait_item_span
+                    }
+                }
+                _ => bug!("{:?} is not a method", impl_m)
+            }
+        } else {
+            trait_item_span
+        };
+        let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap();
+        let impl_span = match tcx.map.expect_impl_item(impl_m_node_id).node {
+            ImplItemKind::Method(ref impl_m_sig, _) => {
+                if let Some(arg) = impl_m_sig.decl.inputs.get(
+                    if impl_number_args > 0 {
+                        impl_number_args - 1
+                    } else {
+                        0
+                    }) {
+                    arg.pat.span
+                } else {
+                    impl_m_span
+                }
+            }
+            _ => bug!("{:?} is not a method", impl_m)
+        };
+        let mut err = struct_span_err!(tcx.sess, impl_span, E0050,
             "method `{}` has {} parameter{} \
              but the declaration in trait `{}` has {}",
             trait_m.name,
-            impl_m.fty.sig.0.inputs.len(),
-            if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"},
+            impl_number_args,
+            if impl_number_args == 1 {""} else {"s"},
             tcx.item_path_str(trait_m.def_id),
-            trait_m.fty.sig.0.inputs.len());
+            trait_number_args);
+        if let Some(trait_span) = trait_span {
+            err.span_label(trait_span,
+                           &format!("trait requires {}",
+                                    &if trait_number_args != 1 {
+                                        format!("{} parameters", trait_number_args)
+                                    } else {
+                                        format!("{} parameter", trait_number_args)
+                                    }));
+        }
+        err.span_label(impl_span,
+                       &format!("expected {}, found {}",
+                                &if trait_number_args != 1 {
+                                    format!("{} parameters", trait_number_args)
+                                } else {
+                                    format!("{} parameter", trait_number_args)
+                                },
+                       impl_number_args));
+        err.emit();
         return;
     }
 
diff --git a/src/test/compile-fail/E0050.rs b/src/test/compile-fail/E0050.rs
index 2f7dc96361f..5c53d62709a 100644
--- a/src/test/compile-fail/E0050.rs
+++ b/src/test/compile-fail/E0050.rs
@@ -9,13 +9,20 @@
 // except according to those terms.
 
 trait Foo {
-    fn foo(&self, x: u8) -> bool;
+    fn foo(&self, x: u8) -> bool; //~ NOTE trait requires 2 parameters
+    fn bar(&self, x: u8, y: u8, z: u8); //~ NOTE trait requires 4 parameters
+    fn less(&self); //~ NOTE trait requires 1 parameter
 }
 
 struct Bar;
 
 impl Foo for Bar {
     fn foo(&self) -> bool { true } //~ ERROR E0050
+                                   //~| NOTE expected 2 parameters, found 1
+    fn bar(&self) { } //~ ERROR E0050
+                      //~| NOTE expected 4 parameters, found 1
+    fn less(&self, x: u8, y: u8, z: u8) { } //~ ERROR E0050
+                                            //~| NOTE expected 1 parameter, found 4
 }
 
 fn main() {