diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-06-01 11:33:38 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-06-01 11:35:54 -0700 |
| commit | 0754c8461182252f5f86eca09845ece04b533696 (patch) | |
| tree | 7eb26a1e9bcae72da39325046cd98d422d1f9a66 | |
| parent | 28859472f71cea497dbea12523e69dc23daaff76 (diff) | |
| download | rust-0754c8461182252f5f86eca09845ece04b533696.tar.gz rust-0754c8461182252f5f86eca09845ece04b533696.zip | |
Explain that `impl Trait` introduces an implicit type argument
| -rw-r--r-- | src/librustc_typeck/check/compare_method.rs | 35 | ||||
| -rw-r--r-- | src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr | 5 |
3 files changed, 33 insertions, 8 deletions
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 742f6ed5215..fb83f877ccc 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::<Vec<Span>>() - }) + let arg_spans: Vec<Span> = trait_item.generics.params.iter() + .map(|p| p.span) + .collect(); + let impl_trait_spans: Vec<Span> = 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<Span> = 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 4a71932d1df..ecfa5c69e2f 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 95328473555..30322f88cca 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 |
