about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-11-25 03:04:07 +0000
committerMichael Goulet <michael@errs.io>2024-11-25 03:04:07 +0000
commitd26e29ff3a9c3851045b6d7a03e6bd6010267624 (patch)
treed0389449b5746210b99b9b84e5a9b39417ef51d6
parent15b663e684d0acf1b4299b7ad6b4f4ab106395bd (diff)
downloadrust-d26e29ff3a9c3851045b6d7a03e6bd6010267624.tar.gz
rust-d26e29ff3a9c3851045b6d7a03e6bd6010267624.zip
Tweak parameter mismatch explanation to not say unknown
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs53
-rw-r--r--tests/ui/async-await/coroutine-desc.stderr6
-rw-r--r--tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr2
-rw-r--r--tests/ui/fn/fn-item-type.stderr10
-rw-r--r--tests/ui/fn/param-mismatch-no-names.rs8
-rw-r--r--tests/ui/fn/param-mismatch-no-names.stderr23
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr10
7 files changed, 75 insertions, 37 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 9c18dbd422d..f8f6564cf14 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -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;
@@ -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(&param_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 &params_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(),
+        )
     }
 }
 
diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr
index e1d7898478e..5434ff3d958 100644
--- a/tests/ui/async-await/coroutine-desc.stderr
+++ b/tests/ui/async-await/coroutine-desc.stderr
@@ -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
 
diff --git a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 46723c5a297..5dea3f70fdb 100644
--- a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -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
 
diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr
index 76cdbcceac8..5cc529543d2 100644
--- a/tests/ui/fn/fn-item-type.stderr
+++ b/tests/ui/fn/fn-item-type.stderr
@@ -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
 
diff --git a/tests/ui/fn/param-mismatch-no-names.rs b/tests/ui/fn/param-mismatch-no-names.rs
new file mode 100644
index 00000000000..05f3de190ea
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-no-names.rs
@@ -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() {}
diff --git a/tests/ui/fn/param-mismatch-no-names.stderr b/tests/ui/fn/param-mismatch-no-names.stderr
new file mode 100644
index 00000000000..d9d360d5ae4
--- /dev/null
+++ b/tests/ui/fn/param-mismatch-no-names.stderr
@@ -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`.
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
index a845dfabe93..0a86f884e70 100644
--- a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
@@ -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