]> git.lizzy.rs Git - rust.git/commitdiff
Explain that `impl Trait` introduces an implicit type argument
authorEsteban Küber <esteban@kuber.com.ar>
Sat, 1 Jun 2019 18:33:38 +0000 (11:33 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Sat, 1 Jun 2019 18:35:54 +0000 (11:35 -0700)
src/librustc_typeck/check/compare_method.rs
src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs
src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.stderr

index 742f6ed5215cb7c7ad404827e30b659a27c2ec98..fb83f877ccce241bc90d17f1540379d778945302 100644 (file)
@@ -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();
         }
     }
index 4a71932d1df182555c1221a9ceb8ce4b304092ad..ecfa5c69e2f038ed19bbc6264e017d0d839c4739 100644 (file)
@@ -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() {}
index 953284735553c3d805d21cdba30b6143cea41117..30322f88cca42aa6020b8d84c665b06d86ad508e 100644 (file)
@@ -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