Skip to content

Commit 6f6fe3e

Browse files
authored
Rollup merge of #96466 - compiler-errors:error-collect-array, r=davidtwco
Better error messages when collecting into `[T; n]` Fixes #96461
2 parents d956d01 + 83d701e commit 6f6fe3e

File tree

6 files changed

+69
-32
lines changed

6 files changed

+69
-32
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,42 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
217217
flags.push((sym::_Self, Some(shortname.to_owned())));
218218
}
219219

220+
// Slices give us `[]`, `[{ty}]`
221+
if let ty::Slice(aty) = self_ty.kind() {
222+
flags.push((sym::_Self, Some("[]".to_string())));
223+
if let Some(def) = aty.ty_adt_def() {
224+
// We also want to be able to select the slice's type's original
225+
// signature with no type arguments resolved
226+
let type_string = self.tcx.type_of(def.did()).to_string();
227+
flags.push((sym::_Self, Some(format!("[{type_string}]"))));
228+
}
229+
if aty.is_integral() {
230+
flags.push((sym::_Self, Some("[{integral}]".to_string())));
231+
}
232+
}
233+
234+
// Arrays give us `[]`, `[{ty}; _]` and `[{ty}; N]`
220235
if let ty::Array(aty, len) = self_ty.kind() {
221-
flags.push((sym::_Self, Some("[]".to_owned())));
222-
flags.push((sym::_Self, Some(format!("[{}]", aty))));
236+
flags.push((sym::_Self, Some("[]".to_string())));
237+
let len = len.val().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
238+
flags.push((sym::_Self, Some(format!("[{}; _]", aty))));
239+
if let Some(n) = len {
240+
flags.push((sym::_Self, Some(format!("[{}; {}]", aty, n))));
241+
}
223242
if let Some(def) = aty.ty_adt_def() {
224243
// We also want to be able to select the array's type's original
225244
// signature with no type arguments resolved
226245
let type_string = self.tcx.type_of(def.did()).to_string();
227-
flags.push((sym::_Self, Some(format!("[{}]", type_string))));
228-
229-
let len =
230-
len.val().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
231-
let string = match len {
232-
Some(n) => format!("[{}; {}]", type_string, n),
233-
None => format!("[{}; _]", type_string),
234-
};
235-
flags.push((sym::_Self, Some(string)));
246+
flags.push((sym::_Self, Some(format!("[{type_string}; _]"))));
247+
if let Some(n) = len {
248+
flags.push((sym::_Self, Some(format!("[{type_string}; {n}]"))));
249+
}
250+
}
251+
if aty.is_integral() {
252+
flags.push((sym::_Self, Some("[{integral}; _]".to_string())));
253+
if let Some(n) = len {
254+
flags.push((sym::_Self, Some(format!("[{{integral}}; {n}]"))));
255+
}
236256
}
237257
}
238258
if let ty::Dynamic(traits, _) = self_ty.kind() {

library/core/src/iter/traits/collect.rs

+13-19
Original file line numberDiff line numberDiff line change
@@ -96,30 +96,24 @@
9696
#[rustc_on_unimplemented(
9797
on(
9898
_Self = "[{A}]",
99-
message = "a value of type `{Self}` cannot be built since `{Self}` has no definite size",
99+
message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size",
100100
label = "try explicitly collecting into a `Vec<{A}>`",
101101
),
102102
on(
103-
all(
104-
A = "{integer}",
105-
any(
106-
_Self = "[i8]",
107-
_Self = "[i16]",
108-
_Self = "[i32]",
109-
_Self = "[i64]",
110-
_Self = "[i128]",
111-
_Self = "[isize]",
112-
_Self = "[u8]",
113-
_Self = "[u16]",
114-
_Self = "[u32]",
115-
_Self = "[u64]",
116-
_Self = "[u128]",
117-
_Self = "[usize]"
118-
)
119-
),
120-
message = "a value of type `{Self}` cannot be built since `{Self}` has no definite size",
103+
all(A = "{integer}", any(_Self = "[{integral}]",)),
104+
message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size",
121105
label = "try explicitly collecting into a `Vec<{A}>`",
122106
),
107+
on(
108+
_Self = "[{A}; _]",
109+
message = "an array of type `{Self}` cannot be built directly from an iterator",
110+
label = "try collecting into a `Vec<{A}>`, then using `.try_into()`",
111+
),
112+
on(
113+
all(A = "{integer}", any(_Self = "[{integral}; _]",)),
114+
message = "an array of type `{Self}` cannot be built directly from an iterator",
115+
label = "try collecting into a `Vec<{A}>`, then using `.try_into()`",
116+
),
123117
message = "a value of type `{Self}` cannot be built from an iterator \
124118
over elements of type `{A}`",
125119
label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
//~^ NOTE required by a bound in this
3+
let whatever: [u32; 10] = (0..10).collect();
4+
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
5+
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
6+
//~| NOTE required by a bound in `collect`
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
2+
--> $DIR/collect-into-array.rs:3:39
3+
|
4+
LL | let whatever: [u32; 10] = (0..10).collect();
5+
| ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()`
6+
|
7+
= help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
8+
note: required by a bound in `collect`
9+
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
10+
|
11+
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/iterators/collect-into-slice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ fn process_slice(data: &[i32]) {
66
fn main() {
77
let some_generated_vec = (0..10).collect();
88
//~^ ERROR the size for values of type `[i32]` cannot be known at compilation time
9-
//~| ERROR a value of type `[i32]` cannot be built since `[i32]` has no definite size
9+
//~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size
1010
//~| NOTE try explicitly collecting into a `Vec<{integer}>`
1111
//~| NOTE required by a bound in `collect`
1212
//~| NOTE all local variables must have a statically known size

src/test/ui/iterators/collect-into-slice.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | let some_generated_vec = (0..10).collect();
88
= note: all local variables must have a statically known size
99
= help: unsized locals are gated as an unstable feature
1010

11-
error[E0277]: a value of type `[i32]` cannot be built since `[i32]` has no definite size
11+
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
1212
--> $DIR/collect-into-slice.rs:7:38
1313
|
1414
LL | let some_generated_vec = (0..10).collect();

0 commit comments

Comments
 (0)