]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/compare_method.rs
Point at individual type arguments on arg count mismatch
[rust.git] / src / librustc_typeck / check / compare_method.rs
index b47cce04012a0854e08e4875c73302437c89993f..742f6ed5215cb7c7ad404827e30b659a27c2ec98 100644 (file)
@@ -1,4 +1,5 @@
 use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind};
+use rustc::hir::def::{Res, DefKind};
 use rustc::infer::{self, InferOk};
 use rustc::ty::{self, TyCtxt, GenericParamDefKind};
 use rustc::ty::util::ExplicitSelf;
@@ -23,9 +24,9 @@
 /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
 
 pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                     impl_m: &ty::AssociatedItem,
+                                     impl_m: &ty::AssocItem,
                                      impl_m_span: Span,
-                                     trait_m: &ty::AssociatedItem,
+                                     trait_m: &ty::AssocItem,
                                      impl_trait_ref: ty::TraitRef<'tcx>,
                                      trait_item_span: Option<Span>) {
     debug!("compare_impl_method(impl_trait_ref={:?})",
@@ -73,9 +74,9 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                          impl_m: &ty::AssociatedItem,
+                                          impl_m: &ty::AssocItem,
                                           impl_m_span: Span,
-                                          trait_m: &ty::AssociatedItem,
+                                          trait_m: &ty::AssocItem,
                                           impl_trait_ref: ty::TraitRef<'tcx>)
                                           -> Result<(), ErrorReported> {
     let trait_to_impl_substs = impl_trait_ref.substs;
@@ -356,8 +357,8 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 span: Span,
-                                                impl_m: &ty::AssociatedItem,
-                                                trait_m: &ty::AssociatedItem,
+                                                impl_m: &ty::AssocItem,
+                                                trait_m: &ty::AssocItem,
                                                 trait_generics: &ty::Generics,
                                                 impl_generics: &ty::Generics,
                                                 trait_to_skol_substs: SubstsRef<'tcx>)
@@ -384,7 +385,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // the moment, give a kind of vague error message.
     if trait_params != impl_params {
         let def_span = tcx.sess.source_map().def_span(span);
-        let span = tcx.hir().get_generics_span(impl_m.def_id).unwrap_or(def_span);
+        let span = tcx.hir().get_generics(impl_m.def_id).map(|g| g.span).unwrap_or(def_span);
         let mut err = struct_span_err!(
             tcx.sess,
             span,
@@ -395,7 +396,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         err.span_label(span, "lifetimes do not match method in trait");
         if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) {
             let def_sp = tcx.sess.source_map().def_span(sp);
-            let sp = tcx.hir().get_generics_span(trait_m.def_id).unwrap_or(def_sp);
+            let sp = tcx.hir().get_generics(trait_m.def_id).map(|g| g.span).unwrap_or(def_sp);
             err.span_label(sp, "lifetimes in impl do not match this method in trait");
         }
         err.emit();
@@ -409,9 +410,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
                                                      param_env: ty::ParamEnv<'tcx>,
                                                      terr: &TypeError<'_>,
                                                      cause: &ObligationCause<'tcx>,
-                                                     impl_m: &ty::AssociatedItem,
+                                                     impl_m: &ty::AssocItem,
                                                      impl_sig: ty::FnSig<'tcx>,
-                                                     trait_m: &ty::AssociatedItem,
+                                                     trait_m: &ty::AssocItem,
                                                      trait_sig: ty::FnSig<'tcx>)
                                                      -> (Span, Option<Span>) {
     let tcx = infcx.tcx;
@@ -495,9 +496,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
 }
 
 fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                               impl_m: &ty::AssociatedItem,
+                               impl_m: &ty::AssocItem,
                                impl_m_span: Span,
-                               trait_m: &ty::AssociatedItem,
+                               trait_m: &ty::AssocItem,
                                impl_trait_ref: ty::TraitRef<'tcx>)
                                -> Result<(), ErrorReported>
 {
@@ -509,7 +510,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // inscrutable, particularly for cases where one method has no
     // self.
 
-    let self_string = |method: &ty::AssociatedItem| {
+    let self_string = |method: &ty::AssocItem| {
         let untransformed_self_ty = match method.container {
             ty::ImplContainer(_) => impl_trait_ref.self_ty(),
             ty::TraitContainer(_) => tcx.mk_self_type()
@@ -581,9 +582,9 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn compare_number_of_generics<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    impl_: &ty::AssociatedItem,
-    impl_span: Span,
-    trait_: &ty::AssociatedItem,
+    impl_: &ty::AssocItem,
+    _impl_span: Span,
+    trait_: &ty::AssocItem,
     trait_span: Option<Span>,
 ) -> Result<(), ErrorReported> {
     let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
@@ -599,17 +600,25 @@ fn compare_number_of_generics<'a, 'tcx>(
         if impl_count != trait_count {
             err_occurred = true;
 
-            let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
-            let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
-            let span = if impl_item.generics.params.is_empty()
-                || impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
-                impl_span
+            let trait_spans = if let Some(trait_hir_id) = tcx.hir().as_local_hir_id(trait_.def_id) {
+                let trait_item = tcx.hir().expect_trait_item(trait_hir_id);
+                Some(if trait_item.generics.params.is_empty() {
+                    vec![trait_item.generics.span]
+                } else {
+                    trait_item.generics.params.iter().map(|p| p.span).collect::<Vec<Span>>()
+                })
             } else {
-                impl_item.generics.span
+                trait_span.map(|s| vec![s])
             };
 
+            let impl_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
+            let impl_item = tcx.hir().expect_impl_item(impl_hir_id);
+            // let span = impl_item.generics.span;
+            let spans = impl_item.generics.spans();
+            let span = spans.primary_span();
+
             let mut err = tcx.sess.struct_span_err_with_code(
-                span,
+                spans,
                 &format!(
                     "method `{}` has {} {kind} parameter{} but its trait \
                      declaration has {} {kind} parameter{}",
@@ -625,22 +634,32 @@ fn compare_number_of_generics<'a, 'tcx>(
 
             let mut suffix = None;
 
-            if let Some(span) = trait_span {
-                err.span_label(
-                    span,
-                    format!("expected {} {} parameter{}", trait_count, kind,
-                        if trait_count != 1 { "s" } else { "" })
-                );
+            if let Some(spans) = trait_spans {
+                let mut spans = spans.iter();
+                if let Some(span) = spans.next() {
+                    err.span_label(*span, format!(
+                        "expected {} {} parameter{}",
+                        trait_count,
+                        kind,
+                        if trait_count != 1 { "s" } else { "" },
+                    ));
+                }
+                for span in spans {
+                    err.span_label(*span, "");
+                }
             } else {
                 suffix = Some(format!(", expected {}", trait_count));
             }
 
-            err.span_label(
-                span,
-                format!("found {} {} parameter{}{}", impl_count, kind,
+            if let Some(span) = span {
+                err.span_label(span, format!(
+                    "found {} {} parameter{}{}",
+                    impl_count,
+                    kind,
                     if impl_count != 1 { "s" } else { "" },
-                    suffix.unwrap_or_else(|| String::new())),
-            );
+                    suffix.unwrap_or_else(|| String::new()),
+                ));
+            }
 
             err.emit();
         }
@@ -654,9 +673,9 @@ fn compare_number_of_generics<'a, 'tcx>(
 }
 
 fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                                impl_m: &ty::AssociatedItem,
+                                                impl_m: &ty::AssocItem,
                                                 impl_m_span: Span,
-                                                trait_m: &ty::AssociatedItem,
+                                                trait_m: &ty::AssocItem,
                                                 trait_item_span: Option<Span>)
                                                 -> Result<(), ErrorReported> {
     let impl_m_fty = tcx.fn_sig(impl_m.def_id);
@@ -738,8 +757,8 @@ trait `{}` has {}",
 }
 
 fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                        impl_m: &ty::AssociatedItem,
-                                        trait_m: &ty::AssociatedItem)
+                                        impl_m: &ty::AssocItem,
+                                        trait_m: &ty::AssocItem)
                                         -> Result<(), ErrorReported> {
     // FIXME(chrisvittal) Clean up this function, list of FIXME items:
     //     1. Better messages for the span labels
@@ -844,7 +863,7 @@ fn visit_ty(&mut self, ty: &'v hir::Ty) {
                                 if let hir::TyKind::Path(
                                     hir::QPath::Resolved(None, ref path)) = ty.node
                                 {
-                                    if let hir::def::Def::TyParam(def_id) = path.def {
+                                    if let Res::Def(DefKind::TyParam, def_id) = path.res {
                                         if def_id == self.1 {
                                             self.0 = Some(ty.span);
                                         }
@@ -910,9 +929,9 @@ fn nested_visit_map<'this>(
 }
 
 pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                    impl_c: &ty::AssociatedItem,
+                                    impl_c: &ty::AssocItem,
                                     impl_c_span: Span,
-                                    trait_c: &ty::AssociatedItem,
+                                    trait_c: &ty::AssocItem,
                                     impl_trait_ref: ty::TraitRef<'tcx>) {
     debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);