Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak parameter mismatch explanation to not say {unknown} #133430

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 &params_with_generics {
// Param has to have a generic and be matched to be relevant
if matched_inputs[idx.into()].is_none() {
continue;
Expand All @@ -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()
{
Expand All @@ -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)
})
Expand All @@ -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;
}
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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(&param_idents_matching),
if param_idents_matching.len() == 2 { "both" } else { "all" },
generic_param.name.ident().name,
),
);
Expand Down Expand Up @@ -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 &params_with_generics {
if matched_inputs[idx.into()].is_none() {
continue;
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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()?;

Expand Down Expand Up @@ -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(),
)
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/async-await/coroutine-desc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/fn/fn-item-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down
8 changes: 8 additions & 0 deletions tests/ui/fn/param-mismatch-no-names.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions tests/ui/fn/param-mismatch-no-names.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down
Loading