diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 742f6ed5215cb..fb83f877ccce2 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -600,20 +600,37 @@ fn compare_number_of_generics<'a, 'tcx>( if impl_count != trait_count { err_occurred = true; - let trait_spans = if let Some(trait_hir_id) = tcx.hir().as_local_hir_id(trait_.def_id) { + let ( + trait_spans, + impl_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] + if trait_item.generics.params.is_empty() { + (Some(vec![trait_item.generics.span]), vec![]) } else { - trait_item.generics.params.iter().map(|p| p.span).collect::>() - }) + let arg_spans: Vec = trait_item.generics.params.iter() + .map(|p| p.span) + .collect(); + let impl_trait_spans: Vec = trait_item.generics.params.iter() + .filter_map(|p| if !trait_item.generics.span.overlaps(p.span) { + Some(p.span) + } else { + None + }).collect(); + (Some(arg_spans), impl_trait_spans) + } } else { - trait_span.map(|s| vec![s]) + (trait_span.map(|s| vec![s]), vec![]) }; 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 impl_item_impl_trait_spans: Vec = impl_item.generics.params.iter() + .filter_map(|p| if !impl_item.generics.span.overlaps(p.span) { + Some(p.span) + } else { + None + }).collect(); let spans = impl_item.generics.spans(); let span = spans.primary_span(); @@ -661,6 +678,10 @@ fn compare_number_of_generics<'a, 'tcx>( )); } + for span in impl_trait_spans.iter().chain(impl_item_impl_trait_spans.iter()) { + err.span_label(*span, "`impl Trait` introduces an implicit type parameter"); + } + err.emit(); } } diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs index 4a71932d1df18..ecfa5c69e2f03 100644 --- a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs +++ b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs @@ -10,6 +10,7 @@ impl Foo for u32 { fn foo(&self, t: impl Clone) {} //~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters //~| NOTE found 1 type parameter +//~| NOTE `impl Trait` introduces an implicit type parameter } fn main() {} diff --git a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr index 953284735553c..30322f88cca42 100644 --- a/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr +++ b/src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr @@ -5,7 +5,10 @@ LL | fn foo(&self, t: Self::T); | - expected 0 type parameters ... LL | fn foo(&self, t: impl Clone) {} - | ^^^^^^^^^^ found 1 type parameter + | ^^^^^^^^^^ + | | + | found 1 type parameter + | `impl Trait` introduces an implicit type parameter error: aborting due to previous error