diff options
| author | Michael Goulet <michael@errs.io> | 2022-04-26 21:09:26 -0700 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-04-26 21:37:10 -0700 |
| commit | 83d701e569914b9dbf7be002f62d63e790a5cb70 (patch) | |
| tree | 20c1709a18e363bed2de5f137ca6e4bddb44916f | |
| parent | a7197189cd0e3a86d1b661d1dceb8bdff021d0b8 (diff) | |
| download | rust-83d701e569914b9dbf7be002f62d63e790a5cb70.tar.gz rust-83d701e569914b9dbf7be002f62d63e790a5cb70.zip | |
Better error messages when collecting into `[T; n]`
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs | 42 | ||||
| -rw-r--r-- | library/core/src/iter/traits/collect.rs | 32 | ||||
| -rw-r--r-- | src/test/ui/iterators/collect-into-array.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/iterators/collect-into-array.stderr | 16 | ||||
| -rw-r--r-- | src/test/ui/iterators/collect-into-slice.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/iterators/collect-into-slice.stderr | 2 |
6 files changed, 69 insertions, 32 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 31b92d52beb..9e9c230aebb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -217,22 +217,42 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { flags.push((sym::_Self, Some(shortname.to_owned()))); } + // Slices give us `[]`, `[{ty}]` + if let ty::Slice(aty) = self_ty.kind() { + flags.push((sym::_Self, Some("[]".to_string()))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the slice's type's original + // signature with no type arguments resolved + let type_string = self.tcx.type_of(def.did()).to_string(); + flags.push((sym::_Self, Some(format!("[{type_string}]")))); + } + if aty.is_integral() { + flags.push((sym::_Self, Some("[{integral}]".to_string()))); + } + } + + // Arrays give us `[]`, `[{ty}; _]` and `[{ty}; N]` if let ty::Array(aty, len) = self_ty.kind() { - flags.push((sym::_Self, Some("[]".to_owned()))); - flags.push((sym::_Self, Some(format!("[{}]", aty)))); + flags.push((sym::_Self, Some("[]".to_string()))); + let len = len.val().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); + flags.push((sym::_Self, Some(format!("[{}; _]", aty)))); + if let Some(n) = len { + flags.push((sym::_Self, Some(format!("[{}; {}]", aty, n)))); + } if let Some(def) = aty.ty_adt_def() { // We also want to be able to select the array's type's original // signature with no type arguments resolved let type_string = self.tcx.type_of(def.did()).to_string(); - flags.push((sym::_Self, Some(format!("[{}]", type_string)))); - - let len = - len.val().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); - let string = match len { - Some(n) => format!("[{}; {}]", type_string, n), - None => format!("[{}; _]", type_string), - }; - flags.push((sym::_Self, Some(string))); + flags.push((sym::_Self, Some(format!("[{type_string}; _]")))); + if let Some(n) = len { + flags.push((sym::_Self, Some(format!("[{type_string}; {n}]")))); + } + } + if aty.is_integral() { + flags.push((sym::_Self, Some("[{integral}; _]".to_string()))); + if let Some(n) = len { + flags.push((sym::_Self, Some(format!("[{{integral}}; {n}]")))); + } } } if let ty::Dynamic(traits, _) = self_ty.kind() { diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e6900742c31..12ca508bed2 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -96,30 +96,24 @@ #[rustc_on_unimplemented( on( _Self = "[{A}]", - message = "a value of type `{Self}` cannot be built since `{Self}` has no definite size", + message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size", label = "try explicitly collecting into a `Vec<{A}>`", ), on( - all( - A = "{integer}", - any( - _Self = "[i8]", - _Self = "[i16]", - _Self = "[i32]", - _Self = "[i64]", - _Self = "[i128]", - _Self = "[isize]", - _Self = "[u8]", - _Self = "[u16]", - _Self = "[u32]", - _Self = "[u64]", - _Self = "[u128]", - _Self = "[usize]" - ) - ), - message = "a value of type `{Self}` cannot be built since `{Self}` has no definite size", + all(A = "{integer}", any(_Self = "[{integral}]",)), + message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size", label = "try explicitly collecting into a `Vec<{A}>`", ), + on( + _Self = "[{A}; _]", + message = "an array of type `{Self}` cannot be built directly from an iterator", + label = "try collecting into a `Vec<{A}>`, then using `.try_into()`", + ), + on( + all(A = "{integer}", any(_Self = "[{integral}; _]",)), + message = "an array of type `{Self}` cannot be built directly from an iterator", + label = "try collecting into a `Vec<{A}>`, then using `.try_into()`", + ), message = "a value of type `{Self}` cannot be built from an iterator \ over elements of type `{A}`", label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`" diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs new file mode 100644 index 00000000000..a1144c8cb8c --- /dev/null +++ b/src/test/ui/iterators/collect-into-array.rs @@ -0,0 +1,7 @@ +fn main() { + //~^ NOTE required by a bound in this + let whatever: [u32; 10] = (0..10).collect(); + //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator + //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` + //~| NOTE required by a bound in `collect` +} diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr new file mode 100644 index 00000000000..7be53a4873b --- /dev/null +++ b/src/test/ui/iterators/collect-into-array.stderr @@ -0,0 +1,16 @@ +error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator + --> $DIR/collect-into-array.rs:3:39 + | +LL | let whatever: [u32; 10] = (0..10).collect(); + | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()` + | + = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]` +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn collect<B: FromIterator<Self::Item>>(self) -> B + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs index 905752dec74..aafa6bc8b95 100644 --- a/src/test/ui/iterators/collect-into-slice.rs +++ b/src/test/ui/iterators/collect-into-slice.rs @@ -6,7 +6,7 @@ fn process_slice(data: &[i32]) { fn main() { let some_generated_vec = (0..10).collect(); //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time - //~| ERROR a value of type `[i32]` cannot be built since `[i32]` has no definite size + //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` //~| NOTE required by a bound in `collect` //~| NOTE all local variables must have a statically known size diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr index 521f239451d..4842e65fe97 100644 --- a/src/test/ui/iterators/collect-into-slice.stderr +++ b/src/test/ui/iterators/collect-into-slice.stderr @@ -8,7 +8,7 @@ LL | let some_generated_vec = (0..10).collect(); = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature -error[E0277]: a value of type `[i32]` cannot be built since `[i32]` has no definite size +error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size --> $DIR/collect-into-slice.rs:7:38 | LL | let some_generated_vec = (0..10).collect(); |
