about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-11-23 05:02:18 +0000
committerMichael Goulet <michael@errs.io>2024-11-24 03:32:11 +0000
commit28970a2cb0885ba7922820d6fb0e14c7e166df9b (patch)
tree4757a2157d38d05b941d4854f82ac9dc28974274
parente48241b5d15da7491d3c8fd4d87f7a183a15b6b4 (diff)
downloadrust-28970a2cb0885ba7922820d6fb0e14c7e166df9b.tar.gz
rust-28970a2cb0885ba7922820d6fb0e14c7e166df9b.zip
Simplify array length mismatch error reporting
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs9
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs13
-rw-r--r--compiler/rustc_type_ir/src/error.rs4
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs2
-rw-r--r--compiler/rustc_type_ir/src/relate.rs15
-rw-r--r--tests/crashes/126359.rs9
-rw-r--r--tests/crashes/131101.rs12
-rw-r--r--tests/ui/array-slice-vec/match_arr_unknown_len.stderr5
-rw-r--r--tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr4
-rw-r--r--tests/ui/const-generics/generic-param-mismatch.stderr5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr4
-rw-r--r--tests/ui/consts/array-literal-len-mismatch.stderr2
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.rs10
-rw-r--r--tests/ui/consts/bad-array-size-in-type-err.stderr21
-rw-r--r--tests/ui/consts/const-array-oob-arith.rs4
-rw-r--r--tests/ui/consts/const-array-oob-arith.stderr4
-rw-r--r--tests/ui/inference/array-len-mismatch.stderr4
18 files changed, 60 insertions, 71 deletions
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index c4d86c3210e..d27205e26ab 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -151,10 +151,6 @@ impl<'tcx> Const<'tcx> {
 }
 
 impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
-    fn try_to_target_usize(self, interner: TyCtxt<'tcx>) -> Option<u64> {
-        self.try_to_target_usize(interner)
-    }
-
     fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self {
         Const::new_infer(tcx, infer)
     }
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 43d243b0584..4a82af32559 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -58,12 +58,9 @@ impl<'tcx> TypeError<'tcx> {
                 pluralize!(values.found)
             )
             .into(),
-            TypeError::FixedArraySize(values) => format!(
-                "expected an array with a fixed size of {} element{}, found one with {} element{}",
-                values.expected,
-                pluralize!(values.expected),
-                values.found,
-                pluralize!(values.found)
+            TypeError::ArraySize(values) => format!(
+                "expected an array with a size of {}, found one with a size of {}",
+                values.expected, values.found,
             )
             .into(),
             TypeError::ArgCount => "incorrect number of function parameters".into(),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index c7ad14ac0bf..0f9d4cb1982 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -1792,12 +1792,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
     fn suggest_specify_actual_length(
         &self,
-        terr: TypeError<'_>,
-        trace: &TypeTrace<'_>,
+        terr: TypeError<'tcx>,
+        trace: &TypeTrace<'tcx>,
         span: Span,
     ) -> Option<TypeErrorAdditionalDiags> {
         let hir = self.tcx.hir();
-        let TypeError::FixedArraySize(sz) = terr else {
+        let TypeError::ArraySize(sz) = terr else {
             return None;
         };
         let tykind = match self.tcx.hir_node_by_def_id(trace.cause.body_id) {
@@ -1838,9 +1838,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         if let Some(tykind) = tykind
             && let hir::TyKind::Array(_, length) = tykind
             && let hir::ArrayLen::Body(ct) = length
+            && let Some((scalar, ty)) = sz.found.try_to_scalar()
+            && ty == self.tcx.types.usize
         {
             let span = ct.span();
-            Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found })
+            Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength {
+                span,
+                length: scalar.to_target_usize(&self.tcx).unwrap(),
+            })
         } else {
             None
         }
diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs
index 59dea769511..55671b84dbc 100644
--- a/compiler/rustc_type_ir/src/error.rs
+++ b/compiler/rustc_type_ir/src/error.rs
@@ -29,7 +29,7 @@ pub enum TypeError<I: Interner> {
     Mutability,
     ArgumentMutability(usize),
     TupleSize(ExpectedFound<usize>),
-    FixedArraySize(ExpectedFound<u64>),
+    ArraySize(ExpectedFound<I::Const>),
     ArgCount,
 
     RegionsDoesNotOutlive(I::Region, I::Region),
@@ -69,7 +69,7 @@ impl<I: Interner> TypeError<I> {
         use self::TypeError::*;
         match self {
             CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | PolarityMismatch(_) | Mismatch
-            | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
+            | AbiMismatch(_) | ArraySize(_) | ArgumentSorts(..) | Sorts(_)
             | VariadicMismatch(_) | TargetFeatureCast(_) => false,
 
             Mutability
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 3793d2c5241..a201f2b1c11 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -257,8 +257,6 @@ pub trait Const<I: Interner<Const = Self>>:
     + Relate<I>
     + Flags
 {
-    fn try_to_target_usize(self, interner: I) -> Option<u64>;
-
     fn new_infer(interner: I, var: ty::InferConst) -> Self;
 
     fn new_var(interner: I, var: ty::ConstVid) -> Self;
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 6b301b16060..0b013b2017f 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -501,19 +501,10 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
             let t = relation.relate(a_t, b_t)?;
             match relation.relate(sz_a, sz_b) {
                 Ok(sz) => Ok(Ty::new_array_with_const_len(cx, t, sz)),
-                Err(err) => {
-                    // Check whether the lengths are both concrete/known values,
-                    // but are unequal, for better diagnostics.
-                    let sz_a = sz_a.try_to_target_usize(cx);
-                    let sz_b = sz_b.try_to_target_usize(cx);
-
-                    match (sz_a, sz_b) {
-                        (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => {
-                            Err(TypeError::FixedArraySize(ExpectedFound::new(sz_a_val, sz_b_val)))
-                        }
-                        _ => Err(err),
-                    }
+                Err(TypeError::ConstMismatch(_)) => {
+                    Err(TypeError::ArraySize(ExpectedFound::new(sz_a, sz_b)))
                 }
+                Err(e) => Err(e),
             }
         }
 
diff --git a/tests/crashes/126359.rs b/tests/crashes/126359.rs
deleted file mode 100644
index 4b28c466b55..00000000000
--- a/tests/crashes/126359.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: rust-lang/rust#126359
-
-struct OppOrder<const N: u8 = 3, T = u32> {
-    arr: [T; N],
-}
-
-fn main() {
-    let _ = OppOrder::<3, u32> { arr: [0, 0, 0] };
-}
diff --git a/tests/crashes/131101.rs b/tests/crashes/131101.rs
deleted file mode 100644
index 3ec441101b7..00000000000
--- a/tests/crashes/131101.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #131101
-trait Foo<const N: u8> {
-    fn do_x(&self) -> [u8; N];
-}
-
-struct Bar;
-
-impl Foo<const 3> for Bar {
-    fn do_x(&self) -> [u8; 3] {
-        [0u8; 3]
-    }
-}
diff --git a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
index 3ed0d6bdf3a..f617ff33938 100644
--- a/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
+++ b/tests/ui/array-slice-vec/match_arr_unknown_len.stderr
@@ -2,10 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/match_arr_unknown_len.rs:3:9
    |
 LL |         [1, 2] => true,
-   |         ^^^^^^ expected `2`, found `N`
-   |
-   = note: expected array `[u32; 2]`
-              found array `[u32; N]`
+   |         ^^^^^^ expected an array with a size of 2, found one with a size of N
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
index d5eefd35753..f58821283e1 100644
--- a/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
+++ b/tests/ui/const-generics/const-argument-cross-crate-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:6:67
    |
 LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
-   |                                         ------------------------- ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                                         ------------------------- ^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                                         |
    |                                         arguments to this struct are incorrect
    |
@@ -16,7 +16,7 @@ error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:8:65
    |
 LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
-   |                                       ------------------------- ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+   |                                       ------------------------- ^^^^^^^^^^^^^^^ expected an array with a size of 2, found one with a size of 3
    |                                       |
    |                                       arguments to this struct are incorrect
    |
diff --git a/tests/ui/const-generics/generic-param-mismatch.stderr b/tests/ui/const-generics/generic-param-mismatch.stderr
index be6b3b90ec7..099ce03317d 100644
--- a/tests/ui/const-generics/generic-param-mismatch.stderr
+++ b/tests/ui/const-generics/generic-param-mismatch.stderr
@@ -4,10 +4,7 @@ error[E0308]: mismatched types
 LL | fn test<const N: usize, const M: usize>() -> [u8; M] {
    |                                              ------- expected `[u8; M]` because of return type
 LL |     [0; N]
-   |     ^^^^^^ expected `M`, found `N`
-   |
-   = note: expected array `[u8; M]`
-              found array `[u8; N]`
+   |     ^^^^^^ expected an array with a size of M, found one with a size of N
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
index 14c67e2528a..8efd433fd1f 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
@@ -10,12 +10,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-62504.rs:18:21
    |
 LL |         ArrayHolder([0; Self::SIZE])
-   |         ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+   |         ----------- ^^^^^^^^^^^^^^^ expected an array with a size of X, found one with a size of Self::SIZE
    |         |
    |         arguments to this struct are incorrect
    |
-   = note: expected array `[u32; X]`
-              found array `[u32; Self::SIZE]`
 note: tuple struct defined here
   --> $DIR/issue-62504.rs:14:8
    |
diff --git a/tests/ui/consts/array-literal-len-mismatch.stderr b/tests/ui/consts/array-literal-len-mismatch.stderr
index a11506ecb6d..39b8a647324 100644
--- a/tests/ui/consts/array-literal-len-mismatch.stderr
+++ b/tests/ui/consts/array-literal-len-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/array-literal-len-mismatch.rs:1:26
    |
 LL | const NUMBERS: [u8; 3] = [10, 20];
-   |                     -    ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                     -    ^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                     |
    |                     help: consider specifying the actual array length: `2`
 
diff --git a/tests/ui/consts/bad-array-size-in-type-err.rs b/tests/ui/consts/bad-array-size-in-type-err.rs
new file mode 100644
index 00000000000..cb02ad3205d
--- /dev/null
+++ b/tests/ui/consts/bad-array-size-in-type-err.rs
@@ -0,0 +1,10 @@
+struct BadArraySize<const N: u8> {
+    arr: [i32; N],
+    //~^ ERROR the constant `N` is not of type `usize`
+}
+
+fn main() {
+    let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+    //~^ ERROR mismatched types
+    //~| ERROR the constant `2` is not of type `usize`
+}
diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr
new file mode 100644
index 00000000000..25d14d80c3e
--- /dev/null
+++ b/tests/ui/consts/bad-array-size-in-type-err.stderr
@@ -0,0 +1,21 @@
+error: the constant `N` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:2:10
+   |
+LL |     arr: [i32; N],
+   |          ^^^^^^^^ expected `usize`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/bad-array-size-in-type-err.rs:7:38
+   |
+LL |     let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+   |                                      ^^^^^^^^^ expected an array with a size of 2, found one with a size of 3
+
+error: the constant `2` is not of type `usize`
+  --> $DIR/bad-array-size-in-type-err.rs:7:38
+   |
+LL |     let _ = BadArraySize::<2> { arr: [0, 0, 0] };
+   |                                      ^^^^^^^^^ expected `usize`, found `u8`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-array-oob-arith.rs b/tests/ui/consts/const-array-oob-arith.rs
index 9332cbbd4d7..0f6e76768cd 100644
--- a/tests/ui/consts/const-array-oob-arith.rs
+++ b/tests/ui/consts/const-array-oob-arith.rs
@@ -4,10 +4,10 @@ const VAL: i32 = ARR[IDX];
 const BONG: [i32; (ARR[0] - 41) as usize] = [5];
 const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
 //~^ ERROR: mismatched types
-//~| expected an array with a fixed size of 2 elements, found one with 1 element
+//~| expected an array
 const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
 //~^ ERROR: mismatched types
-//~| expected an array with a fixed size of 1 element, found one with 2 elements
+//~| expected an array
 
 fn main() {
     let _ = VAL;
diff --git a/tests/ui/consts/const-array-oob-arith.stderr b/tests/ui/consts/const-array-oob-arith.stderr
index 029d94273fa..d3299082aa1 100644
--- a/tests/ui/consts/const-array-oob-arith.stderr
+++ b/tests/ui/consts/const-array-oob-arith.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/const-array-oob-arith.rs:5:45
    |
 LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
-   |                   ----------------------    ^^^ expected an array with a fixed size of 2 elements, found one with 1 element
+   |                   ----------------------    ^^^ expected an array with a size of 2, found one with a size of 1
    |                   |
    |                   help: consider specifying the actual array length: `1`
 
@@ -10,7 +10,7 @@ error[E0308]: mismatched types
   --> $DIR/const-array-oob-arith.rs:8:44
    |
 LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
-   |                  ----------------------    ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements
+   |                  ----------------------    ^^^^^^^ expected an array with a size of 1, found one with a size of 2
    |                  |
    |                  help: consider specifying the actual array length: `2`
 
diff --git a/tests/ui/inference/array-len-mismatch.stderr b/tests/ui/inference/array-len-mismatch.stderr
index 7358e478397..7146e3803d5 100644
--- a/tests/ui/inference/array-len-mismatch.stderr
+++ b/tests/ui/inference/array-len-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/array-len-mismatch.rs:6:26
    |
 LL |     let wrong: [u8; 3] = [10, 20];
-   |                -------   ^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                -------   ^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                |    |
    |                |    help: consider specifying the actual array length: `2`
    |                expected due to this
@@ -11,7 +11,7 @@ error[E0308]: mismatched types
   --> $DIR/array-len-mismatch.rs:9:26
    |
 LL |     let wrong: [u8; 3] = returns_arr();
-   |                -------   ^^^^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                -------   ^^^^^^^^^^^^^ expected an array with a size of 3, found one with a size of 2
    |                |    |
    |                |    help: consider specifying the actual array length: `2`
    |                expected due to this