about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2022-12-28 09:26:30 -0800
committerEsteban Küber <esteban@kuber.com.ar>2022-12-28 11:03:28 -0800
commit083eb936ec0fd05fc6c227e5aa2992971f1fe2d1 (patch)
treecaed52c7a54304ce9a58e1a775868ed8e35bb1cf
parent92c1937a90e5b6f20fa6e87016d6869da363972e (diff)
downloadrust-083eb936ec0fd05fc6c227e5aa2992971f1fe2d1.tar.gz
rust-083eb936ec0fd05fc6c227e5aa2992971f1fe2d1.zip
On unsized locals with explicit types suggest `&`
Fix #72742.
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs9
-rw-r--r--src/test/ui/unsized-locals/suggest-borrow.rs7
-rw-r--r--src/test/ui/unsized-locals/suggest-borrow.stderr60
-rw-r--r--src/test/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr4
-rw-r--r--src/test/ui/unsized/unsized6.stderr16
5 files changed, 96 insertions, 0 deletions
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<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized>(x: &X) {
 LL + fn f1<W: ?Sized, X: ?Sized, Y, Z: ?Sized>(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: ?Sized, Y: ?Sized>(x: &X) {
 LL + fn f2<X, Y: ?Sized>(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<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
 LL + fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
    |
+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<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
 LL + fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
    |
+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