Skip to content

Commit df8b0df

Browse files
authored
Rollup merge of rust-lang#111612 - ChayimFriedman2:collect-into-slice-ref, r=petrochenkov
Give better error when collecting into `&[T]` The detection of slice reference of `{integral}` in `rustc_on_unimplemented` is hacky, but a proper solution requires changing `FmtPrinter` to add a parameter to print integers as `{integral}` and I didn't want to change it just for `rustc_on_unimplemented`. I can do that if requested, though. I'm open to better wording; this is the best I could come up with.
2 parents 47fe1a3 + 83930ec commit df8b0df

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

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

+8
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
306306
}
307307
}
308308
}
309+
310+
// `&[{integral}]` - `FromIterator` needs that.
311+
if let ty::Ref(_, ref_ty, rustc_ast::Mutability::Not) = self_ty.kind()
312+
&& let ty::Slice(sty) = ref_ty.kind()
313+
&& sty.is_integral()
314+
{
315+
flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
316+
}
309317
});
310318

311319
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {

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

+10
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@
9494
/// ```
9595
#[stable(feature = "rust1", since = "1.0.0")]
9696
#[rustc_on_unimplemented(
97+
on(
98+
_Self = "&[{A}]",
99+
message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
100+
label = "try explicitly collecting into a `Vec<{A}>`",
101+
),
102+
on(
103+
all(A = "{integer}", any(_Self = "&[{integral}]",)),
104+
message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
105+
label = "try explicitly collecting into a `Vec<{A}>`",
106+
),
97107
on(
98108
_Self = "[{A}]",
99109
message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size",

tests/ui/iterators/collect-into-slice.rs

+6
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@ fn main() {
1414
//~| NOTE doesn't have a size known at compile-time
1515
//~| NOTE doesn't have a size known at compile-time
1616
process_slice(&some_generated_vec);
17+
18+
let some_generated_vec = (0..10).collect();
19+
//~^ ERROR a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
20+
//~| NOTE try explicitly collecting into a `Vec<{integer}>`
21+
//~| NOTE required by a bound in `collect`
22+
process_slice(some_generated_vec);
1723
}

tests/ui/iterators/collect-into-slice.stderr

+11-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ LL | let some_generated_vec = (0..10).collect();
2828
note: required by a bound in `collect`
2929
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
3030

31-
error: aborting due to 3 previous errors
31+
error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
32+
--> $DIR/collect-into-slice.rs:18:38
33+
|
34+
LL | let some_generated_vec = (0..10).collect();
35+
| ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
36+
|
37+
= help: the trait `FromIterator<{integer}>` is not implemented for `&[i32]`
38+
note: required by a bound in `collect`
39+
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
40+
41+
error: aborting due to 4 previous errors
3242

3343
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)