Rollup merge of #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.
This commit is contained in:
Dylan DPC 2023-05-23 00:32:18 +05:30 committed by GitHub
commit df8b0dfc27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 1 deletions

View File

@ -306,6 +306,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
}
// `&[{integral}]` - `FromIterator` needs that.
if let ty::Ref(_, ref_ty, rustc_ast::Mutability::Not) = self_ty.kind()
&& let ty::Slice(sty) = ref_ty.kind()
&& sty.is_integral()
{
flags.push((sym::_Self, Some("&[{integral}]".to_owned())));
}
});
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) {

View File

@ -94,6 +94,16 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
_Self = "&[{A}]",
message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
label = "try explicitly collecting into a `Vec<{A}>`",
),
on(
all(A = "{integer}", any(_Self = "&[{integral}]",)),
message = "a slice of type `{Self}` cannot be built since we need to store the elements somewhere",
label = "try explicitly collecting into a `Vec<{A}>`",
),
on(
_Self = "[{A}]",
message = "a slice of type `{Self}` cannot be built since `{Self}` has no definite size",

View File

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

View File

@ -28,6 +28,16 @@ LL | let some_generated_vec = (0..10).collect();
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
error: aborting due to 3 previous errors
error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere
--> $DIR/collect-into-slice.rs:18:38
|
LL | let some_generated_vec = (0..10).collect();
| ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
|
= help: the trait `FromIterator<{integer}>` is not implemented for `&[i32]`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.