Point at individual type arguments on arg count mismatch
This commit is contained in:
parent
8e595f5610
commit
28859472f7
6 changed files with 76 additions and 29 deletions
|
|
@ -16,7 +16,7 @@ use crate::util::nodemap::{NodeMap, FxHashSet};
|
|||
use crate::mir::mono::Linkage;
|
||||
|
||||
use errors::FatalError;
|
||||
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
|
||||
use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan};
|
||||
use syntax::source_map::Spanned;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
|
||||
|
|
@ -624,6 +624,14 @@ impl Generics {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn spans(&self) -> MultiSpan {
|
||||
if self.params.is_empty() {
|
||||
self.span.into()
|
||||
} else {
|
||||
self.params.iter().map(|p| p.span).collect::<Vec<Span>>().into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Synthetic type parameters are converted to another form during lowering; this allows
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
fn compare_number_of_generics<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl_: &ty::AssocItem,
|
||||
impl_span: Span,
|
||||
_impl_span: Span,
|
||||
trait_: &ty::AssocItem,
|
||||
trait_span: Option<Span>,
|
||||
) -> Result<(), ErrorReported> {
|
||||
|
|
@ -600,17 +600,25 @@ fn compare_number_of_generics<'a, 'tcx>(
|
|||
if impl_count != trait_count {
|
||||
err_occurred = true;
|
||||
|
||||
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 = if impl_item.generics.params.is_empty()
|
||||
|| impl_item.generics.span.is_dummy() { // argument position impl Trait (#55374)
|
||||
impl_span
|
||||
let 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]
|
||||
} else {
|
||||
trait_item.generics.params.iter().map(|p| p.span).collect::<Vec<Span>>()
|
||||
})
|
||||
} else {
|
||||
impl_item.generics.span
|
||||
trait_span.map(|s| vec![s])
|
||||
};
|
||||
|
||||
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 spans = impl_item.generics.spans();
|
||||
let span = spans.primary_span();
|
||||
|
||||
let mut err = tcx.sess.struct_span_err_with_code(
|
||||
span,
|
||||
spans,
|
||||
&format!(
|
||||
"method `{}` has {} {kind} parameter{} but its trait \
|
||||
declaration has {} {kind} parameter{}",
|
||||
|
|
@ -626,22 +634,32 @@ fn compare_number_of_generics<'a, 'tcx>(
|
|||
|
||||
let mut suffix = None;
|
||||
|
||||
if let Some(span) = trait_span {
|
||||
err.span_label(
|
||||
span,
|
||||
format!("expected {} {} parameter{}", trait_count, kind,
|
||||
if trait_count != 1 { "s" } else { "" })
|
||||
);
|
||||
if let Some(spans) = trait_spans {
|
||||
let mut spans = spans.iter();
|
||||
if let Some(span) = spans.next() {
|
||||
err.span_label(*span, format!(
|
||||
"expected {} {} parameter{}",
|
||||
trait_count,
|
||||
kind,
|
||||
if trait_count != 1 { "s" } else { "" },
|
||||
));
|
||||
}
|
||||
for span in spans {
|
||||
err.span_label(*span, "");
|
||||
}
|
||||
} else {
|
||||
suffix = Some(format!(", expected {}", trait_count));
|
||||
}
|
||||
|
||||
err.span_label(
|
||||
span,
|
||||
format!("found {} {} parameter{}{}", impl_count, kind,
|
||||
if let Some(span) = span {
|
||||
err.span_label(span, format!(
|
||||
"found {} {} parameter{}{}",
|
||||
impl_count,
|
||||
kind,
|
||||
if impl_count != 1 { "s" } else { "" },
|
||||
suffix.unwrap_or_else(|| String::new())),
|
||||
);
|
||||
suffix.unwrap_or_else(|| String::new()),
|
||||
));
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,5 +8,15 @@ impl Foo for Bar {
|
|||
fn foo(x: bool) -> Self { Bar } //~ ERROR E0049
|
||||
}
|
||||
|
||||
trait Fuzz {
|
||||
fn fuzz<A: Default, B>(x: A, y: B) -> Self;
|
||||
}
|
||||
|
||||
struct Baz;
|
||||
|
||||
impl Fuzz for Baz {
|
||||
fn fuzz(x: bool, y: bool) -> Self { Baz } //~ ERROR E0049
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
--> $DIR/E0049.rs:8:5
|
||||
--> $DIR/E0049.rs:8:11
|
||||
|
|
||||
LL | fn foo<T: Default>(x: T) -> Self;
|
||||
| --------------------------------- expected 1 type parameter
|
||||
| - expected 1 type parameter
|
||||
...
|
||||
LL | fn foo(x: bool) -> Self { Bar }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ found 0 type parameters
|
||||
| ^ found 0 type parameters
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0049]: method `fuzz` has 0 type parameters but its trait declaration has 2 type parameters
|
||||
--> $DIR/E0049.rs:18:12
|
||||
|
|
||||
LL | fn fuzz<A: Default, B>(x: A, y: B) -> Self;
|
||||
| - -
|
||||
| |
|
||||
| expected 2 type parameters
|
||||
...
|
||||
LL | fn fuzz(x: bool, y: bool) -> Self { Baz }
|
||||
| ^ found 0 type parameters
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0049`.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/issue-36708.rs:8:11
|
||||
--> $DIR/issue-36708.rs:8:12
|
||||
|
|
||||
LL | fn foo<T>() {}
|
||||
| ^^^ found 1 type parameter, expected 0
|
||||
| ^ found 1 type parameter, expected 0
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/type-arg-mismatch-due-to-impl-trait.rs:10:11
|
||||
--> $DIR/type-arg-mismatch-due-to-impl-trait.rs:10:22
|
||||
|
|
||||
LL | fn foo(&self, t: Self::T);
|
||||
| -------------------------- expected 0 type parameters
|
||||
| - expected 0 type parameters
|
||||
...
|
||||
LL | fn foo(&self, t: impl Clone) {}
|
||||
| ^ found 1 type parameter
|
||||
| ^^^^^^^^^^ found 1 type parameter
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue