about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2016-09-10 17:52:26 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2016-09-14 19:03:18 +0200
commit35584629f4f8ad1eb32c4363fb9b5437e1052e5e (patch)
tree25d7220e5c8d564413eb0bf8f20b7213fcf6f0c1
parenta5f4cc527de4230359c81799852f6bc770eba0e6 (diff)
downloadrust-35584629f4f8ad1eb32c4363fb9b5437e1052e5e.tar.gz
rust-35584629f4f8ad1eb32c4363fb9b5437e1052e5e.zip
Update E0049 to new error format
-rw-r--r--src/librustc_typeck/check/compare_method.rs35
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/compile-fail/E0049.rs3
3 files changed, 37 insertions, 5 deletions
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 1604f34d575..faad3f9b000 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -38,7 +38,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                      impl_m_span: Span,
                                      impl_m_body_id: ast::NodeId,
                                      trait_m: &ty::Method<'tcx>,
-                                     impl_trait_ref: &ty::TraitRef<'tcx>) {
+                                     impl_trait_ref: &ty::TraitRef<'tcx>,
+                                     trait_item_span: Option<Span>) {
     debug!("compare_impl_method(impl_trait_ref={:?})",
            impl_trait_ref);
 
@@ -97,14 +98,42 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let num_impl_m_type_params = impl_m.generics.types.len();
     let num_trait_m_type_params = trait_m.generics.types.len();
     if num_impl_m_type_params != num_trait_m_type_params {
-        span_err!(tcx.sess, impl_m_span, E0049,
+        let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap();
+        let span = match tcx.map.expect_impl_item(impl_m_node_id).node {
+            ImplItemKind::Method(ref impl_m_sig, _) => {
+                if impl_m_sig.generics.is_parameterized() {
+                    impl_m_sig.generics.span
+                } else {
+                    impl_m_span
+                }
+            }
+            _ => bug!("{:?} is not a method", impl_m)
+        };
+
+        struct_span_err!(tcx.sess, span, E0049,
             "method `{}` has {} type parameter{} \
              but its trait declaration has {} type parameter{}",
             trait_m.name,
             num_impl_m_type_params,
             if num_impl_m_type_params == 1 {""} else {"s"},
             num_trait_m_type_params,
-            if num_trait_m_type_params == 1 {""} else {"s"});
+            if num_trait_m_type_params == 1 {""} else {"s"})
+            .span_label(trait_item_span.unwrap(),
+                        &format!("expected {}",
+                                 &if num_trait_m_type_params != 1 {
+                                     format!("{} type parameters",
+                                             num_trait_m_type_params)
+                                 } else {
+                                     format!("{} type parameter",
+                                             num_trait_m_type_params)
+                                 }))
+            .span_label(span, &format!("found {}",
+                                       &if num_impl_m_type_params != 1 {
+                                           format!("{} type parameters", num_impl_m_type_params)
+                                       } else {
+                                           format!("1 type parameter")
+                                       }))
+            .emit();
         return;
     }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 005cd2e46b8..455bde9421d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1015,13 +1015,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         _ => span_bug!(impl_item.span, "non-method impl-item for method")
                     };
 
+                    let trait_span = tcx.map.span_if_local(ty_trait_item.def_id());
                     if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
                         compare_impl_method(ccx,
                                             &impl_method,
                                             impl_item.span,
                                             body.id,
                                             &trait_method,
-                                            &impl_trait_ref);
+                                            &impl_trait_ref,
+                                            trait_span);
                     } else {
                         let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
                                   "item `{}` is an associated method, \
diff --git a/src/test/compile-fail/E0049.rs b/src/test/compile-fail/E0049.rs
index 5867e11e9ac..33ebd3f7aca 100644
--- a/src/test/compile-fail/E0049.rs
+++ b/src/test/compile-fail/E0049.rs
@@ -9,13 +9,14 @@
 // except according to those terms.
 
 trait Foo {
-    fn foo<T: Default>(x: T) -> Self;
+    fn foo<T: Default>(x: T) -> Self; //~ NOTE expected 1 type parameter
 }
 
 struct Bar;
 
 impl Foo for Bar {
     fn foo(x: bool) -> Self { Bar } //~ ERROR E0049
+                                    //~| NOTE found 0 type parameters
 }
 
 fn main() {