diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 472086eca8f..26ba3d780d5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2514,6 +2514,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::VariableType(hir_id) => { let parent_node = self.tcx.hir().get_parent_node(hir_id); match self.tcx.hir().find(parent_node) { + Some(Node::Local(hir::Local { ty: Some(ty), .. })) => { + err.span_suggestion_verbose( + ty.span.shrink_to_lo(), + "consider borrowing here", + "&", + Applicability::MachineApplicable, + ); + err.note("all local variables must have a statically known size"); + } Some(Node::Local(hir::Local { init: Some(hir::Expr { kind: hir::ExprKind::Index(_, _), span, .. }), .. diff --git a/src/test/ui/unsized-locals/suggest-borrow.rs b/src/test/ui/unsized-locals/suggest-borrow.rs new file mode 100644 index 00000000000..08694857993 --- /dev/null +++ b/src/test/ui/unsized-locals/suggest-borrow.rs @@ -0,0 +1,7 @@ +fn main() { + let x: [u8] = vec!(1, 2, 3)[..]; //~ ERROR E0277 + let x: &[u8] = vec!(1, 2, 3)[..]; //~ ERROR E0308 + let x: [u8] = &vec!(1, 2, 3)[..]; //~ ERROR E0308 + //~^ ERROR E0277 + let x: &[u8] = &vec!(1, 2, 3)[..]; +} diff --git a/src/test/ui/unsized-locals/suggest-borrow.stderr b/src/test/ui/unsized-locals/suggest-borrow.stderr new file mode 100644 index 00000000000..08745eab28d --- /dev/null +++ b/src/test/ui/unsized-locals/suggest-borrow.stderr @@ -0,0 +1,60 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/suggest-borrow.rs:2:9 + | +LL | let x: [u8] = vec!(1, 2, 3)[..]; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider borrowing here + | +LL | let x: &[u8] = vec!(1, 2, 3)[..]; + | + + +error[E0308]: mismatched types + --> $DIR/suggest-borrow.rs:3:20 + | +LL | let x: &[u8] = vec!(1, 2, 3)[..]; + | ----- ^^^^^^^^^^^^^^^^^ + | | | + | | expected `&[u8]`, found slice `[{integer}]` + | | help: consider borrowing here: `&vec!(1, 2, 3)[..]` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/suggest-borrow.rs:4:19 + | +LL | let x: [u8] = &vec!(1, 2, 3)[..]; + | ---- ^^^^^^^^^^^^^^^^^^ expected slice `[u8]`, found `&[{integer}]` + | | + | expected due to this + | +help: consider removing the borrow + | +LL - let x: [u8] = &vec!(1, 2, 3)[..]; +LL + let x: [u8] = vec!(1, 2, 3)[..]; + | +help: alternatively, consider changing the type annotation + | +LL | let x: &[u8] = &vec!(1, 2, 3)[..]; + | + + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/suggest-borrow.rs:4:9 + | +LL | let x: [u8] = &vec!(1, 2, 3)[..]; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature +help: consider borrowing here + | +LL | let x: &[u8] = &vec!(1, 2, 3)[..]; + | + + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr b/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr index da77026673d..ace5a87187b 100644 --- a/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr +++ b/src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr @@ -27,6 +27,10 @@ LL | let _foo: [u8] = *foo; = help: the trait `Sized` is not implemented for `[u8]` = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature +help: consider borrowing here + | +LL | let _foo: &[u8] = *foo; + | + error: aborting due to 3 previous errors diff --git a/src/test/ui/unsized/unsized6.stderr b/src/test/ui/unsized/unsized6.stderr index 011f2b426c7..18ac1ea1875 100644 --- a/src/test/ui/unsized/unsized6.stderr +++ b/src/test/ui/unsized/unsized6.stderr @@ -14,6 +14,10 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized` LL - fn f1(x: &X) { LL + fn f1(x: &X) { | +help: consider borrowing here + | +LL | let y: &Y; + | + error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:7:12 @@ -62,6 +66,10 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized` LL - fn f2(x: &X) { LL + fn f2(x: &X) { | +help: consider borrowing here + | +LL | let y: &X; + | + error[E0277]: the size for values of type `Y` cannot be known at compilation time --> $DIR/unsized6.rs:17:12 @@ -94,6 +102,10 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized` LL - fn f3(x1: Box, x2: Box, x3: Box) { LL + fn f3(x1: Box, x2: Box, x3: Box) { | +help: consider borrowing here + | +LL | let y: &X = *x1; + | + error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:24:9 @@ -144,6 +156,10 @@ help: consider removing the `?Sized` bound to make the type parameter `Sized` LL - fn f4(x1: Box, x2: Box, x3: Box) { LL + fn f4(x1: Box, x2: Box, x3: Box) { | +help: consider borrowing here + | +LL | let y: &X = *x1; + | + error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized6.rs:32:9