about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-06-01 11:33:38 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-06-01 11:35:54 -0700
commit0754c8461182252f5f86eca09845ece04b533696 (patch)
tree7eb26a1e9bcae72da39325046cd98d422d1f9a66
parent28859472f71cea497dbea12523e69dc23daaff76 (diff)
downloadrust-0754c8461182252f5f86eca09845ece04b533696.tar.gz
rust-0754c8461182252f5f86eca09845ece04b533696.zip
Explain that `impl Trait` introduces an implicit type argument
-rw-r--r--src/librustc_typeck/check/compare_method.rs35
-rw-r--r--src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs1
-rw-r--r--src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr5
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