Skip to content

Commit

Permalink
Explain that impl Trait introduces an implicit type argument
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jun 1, 2019
1 parent 2885947 commit 0754c84
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
35 changes: 28 additions & 7 deletions src/librustc_typeck/check/compare_method.rs
Expand Up @@ -600,20 +600,37 @@ fn compare_number_of_generics<'a, 'tcx>(
if impl_count != trait_count { if impl_count != trait_count {
err_occurred = true; 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); let trait_item = tcx.hir().expect_trait_item(trait_hir_id);
Some(if trait_item.generics.params.is_empty() { if trait_item.generics.params.is_empty() {
vec![trait_item.generics.span] (Some(vec![trait_item.generics.span]), vec![])
} else { } 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 { } 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_hir_id = tcx.hir().as_local_hir_id(impl_.def_id).unwrap();
let impl_item = tcx.hir().expect_impl_item(impl_hir_id); 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 spans = impl_item.generics.spans();
let span = spans.primary_span(); let span = spans.primary_span();


Expand Down Expand Up @@ -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(); err.emit();
} }
} }
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/issues/type-arg-mismatch-due-to-impl-trait.rs
Expand Up @@ -10,6 +10,7 @@ impl Foo for u32 {
fn foo(&self, t: impl Clone) {} fn foo(&self, t: impl Clone) {}
//~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters //~^ ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
//~| NOTE found 1 type parameter //~| NOTE found 1 type parameter
//~| NOTE `impl Trait` introduces an implicit type parameter
} }


fn main() {} fn main() {}
Expand Up @@ -5,7 +5,10 @@ LL | fn foo(&self, t: Self::T);
| - expected 0 type parameters | - expected 0 type parameters
... ...
LL | fn foo(&self, t: impl Clone) {} 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 error: aborting due to previous error


Expand Down

0 comments on commit 0754c84

Please sign in to comment.