mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 22:37:34 +00:00
Tweak parameter mismatch explanation to not say unknown
This commit is contained in:
parent
15b663e684
commit
d26e29ff3a
@ -2347,9 +2347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let check_for_matched_generics = || {
|
||||
if matched_inputs.iter().any(|x| x.is_some())
|
||||
&& params_with_generics.iter().any(|x| x.0.is_some())
|
||||
&& params_with_generics.iter().any(|x| x.1.is_some())
|
||||
{
|
||||
for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
|
||||
for &(idx, generic, _) in ¶ms_with_generics {
|
||||
// Param has to have a generic and be matched to be relevant
|
||||
if matched_inputs[idx.into()].is_none() {
|
||||
continue;
|
||||
@ -2362,7 +2362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
for unmatching_idx in idx + 1..params_with_generics.len() {
|
||||
if matched_inputs[unmatching_idx.into()].is_none()
|
||||
&& let Some(unmatched_idx_param_generic) =
|
||||
params_with_generics[unmatching_idx].0
|
||||
params_with_generics[unmatching_idx].1
|
||||
&& unmatched_idx_param_generic.name.ident()
|
||||
== generic.name.ident()
|
||||
{
|
||||
@ -2377,8 +2377,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let check_for_matched_generics = check_for_matched_generics();
|
||||
|
||||
for (idx, (generic_param, param)) in
|
||||
params_with_generics.iter().enumerate().filter(|(idx, _)| {
|
||||
for &(idx, generic_param, param) in
|
||||
params_with_generics.iter().filter(|&(idx, _, _)| {
|
||||
check_for_matched_generics
|
||||
|| expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
|
||||
})
|
||||
@ -2390,8 +2390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(other_idx, (other_generic_param, _))| {
|
||||
.filter(|(other_idx, other_generic_param, _)| {
|
||||
if *other_idx == idx {
|
||||
return false;
|
||||
}
|
||||
@ -2410,18 +2409,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
other_generic_param.name.ident() == generic_param.name.ident()
|
||||
})
|
||||
.map(|(other_idx, (_, other_param))| (other_idx, *other_param))
|
||||
.map(|&(other_idx, _, other_param)| (other_idx, other_param))
|
||||
.collect();
|
||||
|
||||
if !other_params_matched.is_empty() {
|
||||
let other_param_matched_names: Vec<String> = other_params_matched
|
||||
.iter()
|
||||
.map(|(_, other_param)| {
|
||||
.map(|(idx, other_param)| {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind
|
||||
{
|
||||
format!("`{ident}`")
|
||||
} else {
|
||||
"{unknown}".to_string()
|
||||
format!("parameter #{}", idx + 1)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -2478,18 +2477,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
{
|
||||
let param_idents_matching: Vec<String> = params_with_generics
|
||||
.iter()
|
||||
.filter(|(generic, _)| {
|
||||
.filter(|(_, generic, _)| {
|
||||
if let Some(generic) = generic {
|
||||
generic.name.ident() == generic_param.name.ident()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.map(|(_, param)| {
|
||||
.map(|(idx, _, param)| {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
|
||||
format!("`{ident}`")
|
||||
} else {
|
||||
"{unknown}".to_string()
|
||||
format!("parameter #{}", idx + 1)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -2498,8 +2497,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
spans.push_span_label(
|
||||
generic_param.span,
|
||||
format!(
|
||||
"{} all reference this parameter {}",
|
||||
"{} {} reference this parameter `{}`",
|
||||
display_list_with_comma_and(¶m_idents_matching),
|
||||
if param_idents_matching.len() == 2 { "both" } else { "all" },
|
||||
generic_param.name.ident().name,
|
||||
),
|
||||
);
|
||||
@ -2580,7 +2580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) {
|
||||
debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
|
||||
for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
|
||||
for &(idx, generic_param, _) in ¶ms_with_generics {
|
||||
if matched_inputs[idx.into()].is_none() {
|
||||
continue;
|
||||
}
|
||||
@ -2594,20 +2594,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let mut idxs_matched: Vec<usize> = vec![];
|
||||
for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
|
||||
|(other_idx, (other_generic_param, _))| {
|
||||
if *other_idx == idx {
|
||||
for &(other_idx, _, _) in
|
||||
params_with_generics.iter().filter(|&&(other_idx, other_generic_param, _)| {
|
||||
if other_idx == idx {
|
||||
return false;
|
||||
}
|
||||
let Some(other_generic_param) = other_generic_param else {
|
||||
return false;
|
||||
};
|
||||
if matched_inputs[(*other_idx).into()].is_some() {
|
||||
if matched_inputs[other_idx.into()].is_some() {
|
||||
return false;
|
||||
}
|
||||
other_generic_param.name.ident() == generic_param.name.ident()
|
||||
},
|
||||
) {
|
||||
})
|
||||
{
|
||||
idxs_matched.push(other_idx);
|
||||
}
|
||||
|
||||
@ -2642,7 +2642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
def_id: DefId,
|
||||
is_method: bool,
|
||||
) -> Option<Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
|
||||
) -> Option<Vec<(usize, Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
|
||||
let fn_node = self.tcx.hir().get_if_local(def_id)?;
|
||||
let fn_decl = fn_node.fn_decl()?;
|
||||
|
||||
@ -2685,7 +2685,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
debug_assert_eq!(params.len(), generic_params.len());
|
||||
Some(generic_params.into_iter().zip(params).collect())
|
||||
Some(
|
||||
generic_params
|
||||
.into_iter()
|
||||
.zip(params)
|
||||
.enumerate()
|
||||
.map(|(a, (b, c))| (a, b, c))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
|
||||
| ^^^ - ----- ----- this parameter needs to match the `async` block type of `f1`
|
||||
| | |
|
||||
| | `f2` needs to match the `async` block type of this parameter
|
||||
| `f1` and `f2` all reference this parameter F
|
||||
| `f1` and `f2` both reference this parameter `F`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coroutine-desc.rs:12:16
|
||||
@ -39,7 +39,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
|
||||
| ^^^ - ----- ----- this parameter needs to match the future type of `f1`
|
||||
| | |
|
||||
| | `f2` needs to match the future type of this parameter
|
||||
| `f1` and `f2` all reference this parameter F
|
||||
| `f1` and `f2` both reference this parameter `F`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/coroutine-desc.rs:14:26
|
||||
@ -62,7 +62,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
|
||||
| ^^^ - ----- ----- this parameter needs to match the `async` closure body type of `f1`
|
||||
| | |
|
||||
| | `f2` needs to match the `async` closure body type of this parameter
|
||||
| `f1` and `f2` all reference this parameter F
|
||||
| `f1` and `f2` both reference this parameter `F`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -16,7 +16,7 @@ LL | fn test<T>(_a: T, _b: T) {}
|
||||
| ^^^^ - ----- ----- this parameter needs to match the `&mut {integer}` type of `_a`
|
||||
| | |
|
||||
| | `_b` needs to match the `&mut {integer}` type of this parameter
|
||||
| `_a` and `_b` all reference this parameter T
|
||||
| `_a` and `_b` both reference this parameter `T`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -17,7 +17,7 @@ LL | fn eq<T>(x: T, y: T) {}
|
||||
| ^^ - ---- ---- this parameter needs to match the fn item type of `x`
|
||||
| | |
|
||||
| | `y` needs to match the fn item type of this parameter
|
||||
| `x` and `y` all reference this parameter T
|
||||
| `x` and `y` both reference this parameter `T`
|
||||
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -39,7 +39,7 @@ LL | fn eq<T>(x: T, y: T) {}
|
||||
| ^^ - ---- ---- this parameter needs to match the fn item type of `x`
|
||||
| | |
|
||||
| | `y` needs to match the fn item type of this parameter
|
||||
| `x` and `y` all reference this parameter T
|
||||
| `x` and `y` both reference this parameter `T`
|
||||
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -61,7 +61,7 @@ LL | fn eq<T>(x: T, y: T) {}
|
||||
| ^^ - ---- ---- this parameter needs to match the fn item type of `x`
|
||||
| | |
|
||||
| | `y` needs to match the fn item type of this parameter
|
||||
| `x` and `y` all reference this parameter T
|
||||
| `x` and `y` both reference this parameter `T`
|
||||
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -83,7 +83,7 @@ LL | fn eq<T>(x: T, y: T) {}
|
||||
| ^^ - ---- ---- this parameter needs to match the fn item type of `x`
|
||||
| | |
|
||||
| | `y` needs to match the fn item type of this parameter
|
||||
| `x` and `y` all reference this parameter T
|
||||
| `x` and `y` both reference this parameter `T`
|
||||
= help: consider casting both fn items to fn pointers using `as fn()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -105,7 +105,7 @@ LL | fn eq<T>(x: T, y: T) {}
|
||||
| ^^ - ---- ---- this parameter needs to match the fn item type of `x`
|
||||
| | |
|
||||
| | `y` needs to match the fn item type of this parameter
|
||||
| `x` and `y` all reference this parameter T
|
||||
| `x` and `y` both reference this parameter `T`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
8
tests/ui/fn/param-mismatch-no-names.rs
Normal file
8
tests/ui/fn/param-mismatch-no-names.rs
Normal file
@ -0,0 +1,8 @@
|
||||
fn same_type<T>(_: T, _: T) {}
|
||||
|
||||
fn f<X, Y>(x: X, y: Y) {
|
||||
same_type([x], Some(y));
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
23
tests/ui/fn/param-mismatch-no-names.stderr
Normal file
23
tests/ui/fn/param-mismatch-no-names.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/param-mismatch-no-names.rs:4:20
|
||||
|
|
||||
LL | same_type([x], Some(y));
|
||||
| --------- --- ^^^^^^^ expected `[X; 1]`, found `Option<Y>`
|
||||
| | |
|
||||
| | expected all arguments to be this `[X; 1]` type because they need to match the type of this parameter
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
= note: expected array `[X; 1]`
|
||||
found enum `Option<Y>`
|
||||
note: function defined here
|
||||
--> $DIR/param-mismatch-no-names.rs:1:4
|
||||
|
|
||||
LL | fn same_type<T>(_: T, _: T) {}
|
||||
| ^^^^^^^^^ - ---- ---- this parameter needs to match the `[X; 1]` type of parameter #1
|
||||
| | |
|
||||
| | parameter #2 needs to match the `[X; 1]` type of this parameter
|
||||
| parameter #1 and parameter #2 both reference this parameter `T`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -14,7 +14,7 @@ LL | fn foo<T>(a: T, b: T) {}
|
||||
| ^^^ - ---- ---- this parameter needs to match the integer type of `a`
|
||||
| | |
|
||||
| | `b` needs to match the integer type of this parameter
|
||||
| `a` and `b` all reference this parameter T
|
||||
| `a` and `b` both reference this parameter `T`
|
||||
|
||||
error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/generic-mismatch-reporting-issue-116615.rs:8:5
|
||||
@ -38,7 +38,7 @@ LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
|
||||
| | | | this parameter needs to match the `&str` type of `a` and `b`
|
||||
| | | `c`, `d` and `e` need to match the `&str` type of this parameter
|
||||
| | `c`, `d` and `e` need to match the `&str` type of this parameter
|
||||
| `a`, `b`, `c`, `d` and `e` all reference this parameter T
|
||||
| `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
|
||||
|
||||
error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/generic-mismatch-reporting-issue-116615.rs:10:5
|
||||
@ -65,8 +65,8 @@ LL | fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
|
||||
| | | | | `d` and `e` need to match the `&str` type of this parameter
|
||||
| | | | `d` and `e` need to match the `&str` type of this parameter
|
||||
| | | `d` and `e` need to match the `&str` type of this parameter
|
||||
| | `a`, `b`, `c`, `d` and `e` all reference this parameter T
|
||||
| `f` and `g` all reference this parameter S
|
||||
| | `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
|
||||
| `f` and `g` both reference this parameter `S`
|
||||
|
||||
error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/generic-mismatch-reporting-issue-116615.rs:12:5
|
||||
@ -90,7 +90,7 @@ LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
|
||||
| | | | this parameter needs to match the `&str` type of `a`, `d` and `e`
|
||||
| | | this parameter needs to match the `&str` type of `a`, `d` and `e`
|
||||
| | `b` and `c` need to match the `&str` type of this parameter
|
||||
| `a`, `b`, `c`, `d` and `e` all reference this parameter T
|
||||
| `a`, `b`, `c`, `d` and `e` all reference this parameter `T`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user