about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMasaki Hara <ackie.h.gmai@gmail.com>2018-05-29 00:11:34 +0900
committerMasaki Hara <ackie.h.gmai@gmail.com>2018-08-19 08:07:33 +0900
commite2b95cb70e2142aab82a40115d11ff54a975335e (patch)
treec8e4c91ad14abd3a6b82ec3a51be94167cf14a4f
parent7f05304068bf6a3b84b328ad6911f6645a0dbf40 (diff)
downloadrust-e2b95cb70e2142aab82a40115d11ff54a975335e.tar.gz
rust-e2b95cb70e2142aab82a40115d11ff54a975335e.zip
Lift some Sized checks.
-rw-r--r--src/librustc/traits/error_reporting.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs45
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/test/compile-fail/unsized-locals/unsized-exprs.rs36
-rw-r--r--src/test/compile-fail/unsized-locals/unsized-exprs2.rs36
-rw-r--r--src/test/ui/associated-types/associated-types-unsized.stderr1
-rw-r--r--src/test/ui/error-codes/E0277.stderr1
-rw-r--r--src/test/ui/feature-gate-unsized_locals.stderr1
-rw-r--r--src/test/ui/issues/issue-15756.stderr1
-rw-r--r--src/test/ui/issues/issue-27078.stderr1
-rw-r--r--src/test/ui/issues/issue-38954.stderr1
-rw-r--r--src/test/ui/issues/issue-41229-ref-str.stderr1
-rw-r--r--src/test/ui/issues/issue-42312.stderr2
-rw-r--r--src/test/ui/issues/issue-5883.stderr1
-rw-r--r--src/test/ui/resolve/issue-5035-2.stderr1
-rw-r--r--src/test/ui/str/str-array-assignment.stderr1
-rw-r--r--src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr1
-rw-r--r--src/test/ui/unsized6.stderr10
18 files changed, 140 insertions, 14 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index bedee5dae5d..23736b1c77b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1454,9 +1454,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
             ObligationCauseCode::VariableType(_) => {
                 err.note("all local variables must have a statically known size");
+                if !self.tcx.features().unsized_locals {
+                    err.help("unsized locals are gated as an unstable feature");
+                }
             }
             ObligationCauseCode::SizedArgumentType => {
                 err.note("all function arguments must have a statically known size");
+                if !self.tcx.features().unsized_locals {
+                    err.help("unsized locals are gated as an unstable feature");
+                }
             }
             ObligationCauseCode::SizedReturnType => {
                 err.note("the return type of a function must have a \
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 9f790612124..ab83cfe25b5 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -903,11 +903,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     );
                 }
                 self.check_rvalue(mir, rv, location);
-                let trait_ref = ty::TraitRef {
-                    def_id: tcx.lang_items().sized_trait().unwrap(),
-                    substs: tcx.mk_substs_trait(place_ty, &[]),
-                };
-                self.prove_trait_ref(trait_ref, location.interesting());
+                if !self.tcx().features().unsized_locals {
+                    let trait_ref = ty::TraitRef {
+                        def_id: tcx.lang_items().sized_trait().unwrap(),
+                        substs: tcx.mk_substs_trait(place_ty, &[]),
+                    };
+                    self.prove_trait_ref(trait_ref, location.interesting());
+                }
             }
             StatementKind::SetDiscriminant {
                 ref place,
@@ -962,6 +964,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         mir: &Mir<'tcx>,
         term: &Terminator<'tcx>,
         term_location: Location,
+        errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
     ) {
         debug!("check_terminator: {:?}", term);
         let tcx = self.tcx();
@@ -1041,7 +1044,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     &sig,
                 );
                 let sig = self.normalize(sig, term_location);
-                self.check_call_dest(mir, term, &sig, destination, term_location);
+                self.check_call_dest(mir, term, &sig, destination, term_location, errors_buffer);
 
                 self.prove_predicates(
                     sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
@@ -1115,6 +1118,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         sig: &ty::FnSig<'tcx>,
         destination: &Option<(Place<'tcx>, BasicBlock)>,
         term_location: Location,
+        errors_buffer: &mut Option<&mut Vec<Diagnostic>>,
     ) {
         let tcx = self.tcx();
         match *destination {
@@ -1143,6 +1147,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                         terr
                     );
                 }
+
+                // When `#![feature(unsized_locals)]` is not enabled,
+                // this check is done at `check_local`.
+                if self.tcx().features().unsized_locals {
+                    let span = term.source_info.span;
+                    self.ensure_place_sized(dest_ty, span, errors_buffer);
+                }
             }
             None => {
                 // FIXME(canndrew): This is_never should probably be an is_uninhabited
@@ -1309,14 +1320,26 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             LocalKind::Var | LocalKind::Temp => {}
         }
 
-        let span = local_decl.source_info.span;
-        let ty = local_decl.ty;
+        // When `#![feature(unsized_locals)]` is enabled, only function calls
+        // are checked in `check_call_dest`.
+        if !self.tcx().features().unsized_locals {
+            let span = local_decl.source_info.span;
+            let ty = local_decl.ty;
+            self.ensure_place_sized(ty, span, errors_buffer);
+        }
+    }
+
+    fn ensure_place_sized(&mut self,
+                          ty: Ty<'tcx>,
+                          span: Span,
+                          errors_buffer: &mut Option<&mut Vec<Diagnostic>>) {
+        let tcx = self.tcx();
 
         // Erase the regions from `ty` to get a global type.  The
         // `Sized` bound in no way depends on precise regions, so this
         // shouldn't affect `is_sized`.
-        let gcx = self.tcx().global_tcx();
-        let erased_ty = gcx.lift(&self.tcx().erase_regions(&ty)).unwrap();
+        let gcx = tcx.global_tcx();
+        let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
         if !erased_ty.is_sized(gcx.at(span), self.param_env) {
             // in current MIR construction, all non-control-flow rvalue
             // expressions evaluate through `as_temp` or `into` a return
@@ -1838,7 +1861,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 location.statement_index += 1;
             }
 
-            self.check_terminator(mir, block_data.terminator(), location);
+            self.check_terminator(mir, block_data.terminator(), location, &mut errors_buffer);
             self.check_iscleanup(mir, block_data);
         }
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c7b717969ab..f73333df796 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -961,8 +961,10 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
         if let PatKind::Binding(_, _, ident, _) = p.node {
             let var_ty = self.assign(p.span, p.id, None);
 
-            self.fcx.require_type_is_sized(var_ty, p.span,
-                                           traits::VariableType(p.id));
+            if !self.fcx.tcx.features().unsized_locals {
+                self.fcx.require_type_is_sized(var_ty, p.span,
+                                               traits::VariableType(p.id));
+            }
 
             debug!("Pattern binding {} is assigned to {} with type {:?}",
                    ident,
@@ -1048,7 +1050,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
         // for simple cases like `fn foo(x: Trait)`,
         // where we would error once on the parameter as a whole, and once on the binding `x`.
-        if arg.pat.simple_ident().is_none() {
+        if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
             fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
         }
 
diff --git a/src/test/compile-fail/unsized-locals/unsized-exprs.rs b/src/test/compile-fail/unsized-locals/unsized-exprs.rs
new file mode 100644
index 00000000000..a09ccbb407e
--- /dev/null
+++ b/src/test/compile-fail/unsized-locals/unsized-exprs.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unsized_tuple_coercion, unsized_locals)]
+
+struct A<X: ?Sized>(X);
+
+fn udrop<T: ?Sized>(_x: T) {}
+fn foo() -> Box<[u8]> {
+    Box::new(*b"foo")
+}
+fn tfoo() -> Box<(i32, [u8])> {
+    Box::new((42, *b"foo"))
+}
+fn afoo() -> Box<A<[u8]>> {
+    Box::new(A(*b"foo"))
+}
+
+impl std::ops::Add<i32> for A<[u8]> {
+    type Output = ();
+    fn add(self, _rhs: i32) -> Self::Output {}
+}
+
+fn main() {
+    udrop::<(i32, [u8])>((42, *foo()));
+    //~^ERROR E0277
+    udrop::<A<[u8]>>(A { 0: *foo() });
+    //~^ERROR E0277
+}
diff --git a/src/test/compile-fail/unsized-locals/unsized-exprs2.rs b/src/test/compile-fail/unsized-locals/unsized-exprs2.rs
new file mode 100644
index 00000000000..40d6e54bd89
--- /dev/null
+++ b/src/test/compile-fail/unsized-locals/unsized-exprs2.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unsized_tuple_coercion, unsized_locals)]
+
+struct A<X: ?Sized>(X);
+
+fn udrop<T: ?Sized>(_x: T) {}
+fn foo() -> Box<[u8]> {
+    Box::new(*b"foo")
+}
+fn tfoo() -> Box<(i32, [u8])> {
+    Box::new((42, *b"foo"))
+}
+fn afoo() -> Box<A<[u8]>> {
+    Box::new(A(*b"foo"))
+}
+
+impl std::ops::Add<i32> for A<[u8]> {
+    type Output = ();
+    fn add(self, _rhs: i32) -> Self::Output {}
+}
+
+fn main() {
+    udrop::<[u8]>(foo()[..]);
+    //~^ERROR cannot move out of indexed content
+    // FIXME: should be error
+    udrop::<A<[u8]>>(A(*foo()));
+}
diff --git a/src/test/ui/associated-types/associated-types-unsized.stderr b/src/test/ui/associated-types/associated-types-unsized.stderr
index 0b338c9ad45..09e3cb8c126 100644
--- a/src/test/ui/associated-types/associated-types-unsized.stderr
+++ b/src/test/ui/associated-types/associated-types-unsized.stderr
@@ -8,6 +8,7 @@ LL |     let x = t.get(); //~ ERROR the size for values of type
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where <T as Get>::Value: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0277.stderr b/src/test/ui/error-codes/E0277.stderr
index e4c2f102267..ab9020222ea 100644
--- a/src/test/ui/error-codes/E0277.stderr
+++ b/src/test/ui/error-codes/E0277.stderr
@@ -8,6 +8,7 @@ LL | fn f(p: Path) { }
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `std::path::Path`
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/E0277.rs:27:5
diff --git a/src/test/ui/feature-gate-unsized_locals.stderr b/src/test/ui/feature-gate-unsized_locals.stderr
index 3cb0aa3b3ec..a0440a373d2 100644
--- a/src/test/ui/feature-gate-unsized_locals.stderr
+++ b/src/test/ui/feature-gate-unsized_locals.stderr
@@ -7,6 +7,7 @@ LL | fn f(f: FnOnce()) {}
    = help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce() + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-15756.stderr b/src/test/ui/issues/issue-15756.stderr
index e142a504eb6..877e0eaedf1 100644
--- a/src/test/ui/issues/issue-15756.stderr
+++ b/src/test/ui/issues/issue-15756.stderr
@@ -7,6 +7,7 @@ LL |     &mut something
    = help: the trait `std::marker::Sized` is not implemented for `[T]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-27078.stderr b/src/test/ui/issues/issue-27078.stderr
index 65b66997ee8..269a69dde33 100644
--- a/src/test/ui/issues/issue-27078.stderr
+++ b/src/test/ui/issues/issue-27078.stderr
@@ -8,6 +8,7 @@ LL |     fn foo(self) -> &'static i32 {
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where Self: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-38954.stderr b/src/test/ui/issues/issue-38954.stderr
index 9ecae90ff3a..9bc937b97c9 100644
--- a/src/test/ui/issues/issue-38954.stderr
+++ b/src/test/ui/issues/issue-38954.stderr
@@ -7,6 +7,7 @@ LL | fn _test(ref _p: str) {}
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all function arguments must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-41229-ref-str.stderr b/src/test/ui/issues/issue-41229-ref-str.stderr
index 75f43be7728..e4a34fdaf48 100644
--- a/src/test/ui/issues/issue-41229-ref-str.stderr
+++ b/src/test/ui/issues/issue-41229-ref-str.stderr
@@ -7,6 +7,7 @@ LL | pub fn example(ref s: str) {}
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all function arguments must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-42312.stderr b/src/test/ui/issues/issue-42312.stderr
index 0f383fe40a5..912d791b6bc 100644
--- a/src/test/ui/issues/issue-42312.stderr
+++ b/src/test/ui/issues/issue-42312.stderr
@@ -8,6 +8,7 @@ LL |     fn baz(_: Self::Target) where Self: Deref {}
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where <Self as std::ops::Deref>::Target: std::marker::Sized` bound
    = note: all function arguments must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `(dyn std::string::ToString + 'static)` cannot be known at compilation time
   --> $DIR/issue-42312.rs:18:23
@@ -18,6 +19,7 @@ LL | pub fn f(_: ToString) {}
    = help: the trait `std::marker::Sized` is not implemented for `(dyn std::string::ToString + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all function arguments must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-5883.stderr b/src/test/ui/issues/issue-5883.stderr
index 6a321abeaed..63dabd86ca8 100644
--- a/src/test/ui/issues/issue-5883.stderr
+++ b/src/test/ui/issues/issue-5883.stderr
@@ -7,6 +7,7 @@ LL | fn new_struct(r: A+'static)
    = help: the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
   --> $DIR/issue-5883.rs:18:8
diff --git a/src/test/ui/resolve/issue-5035-2.stderr b/src/test/ui/resolve/issue-5035-2.stderr
index 10d7a52297f..9e7fca0508e 100644
--- a/src/test/ui/resolve/issue-5035-2.stderr
+++ b/src/test/ui/resolve/issue-5035-2.stderr
@@ -7,6 +7,7 @@ LL | fn foo(_x: K) {}
    = help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/str/str-array-assignment.stderr b/src/test/ui/str/str-array-assignment.stderr
index 59521bd2e2f..57eff3fb137 100644
--- a/src/test/ui/str/str-array-assignment.stderr
+++ b/src/test/ui/str/str-array-assignment.stderr
@@ -30,6 +30,7 @@ LL |   let v = s[..2];
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0308]: mismatched types
   --> $DIR/str-array-assignment.rs:19:17
diff --git a/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr b/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr
index b0c1c284f5a..ecabf9af27b 100644
--- a/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr
+++ b/src/test/ui/traits/trait-bounds-not-on-bare-trait.stderr
@@ -7,6 +7,7 @@ LL | fn foo(_x: Foo + Send) {
    = help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + std::marker::Send + 'static)`
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr
index 5dc12a344ad..5a095332692 100644
--- a/src/test/ui/unsized6.stderr
+++ b/src/test/ui/unsized6.stderr
@@ -8,6 +8,7 @@ LL |     let y: Y;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where Y: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:17:12
@@ -41,6 +42,7 @@ LL |     let y: X;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `Y` cannot be known at compilation time
   --> $DIR/unsized6.rs:27:12
@@ -63,6 +65,7 @@ LL |     let y: X = *x1;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:34:9
@@ -74,6 +77,7 @@ LL |     let y = *x2;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:36:10
@@ -85,6 +89,7 @@ LL |     let (y, z) = (*x3, 4);
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:40:9
@@ -96,6 +101,7 @@ LL |     let y: X = *x1;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:42:9
@@ -107,6 +113,7 @@ LL |     let y = *x2;
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:44:10
@@ -118,6 +125,7 @@ LL |     let (y, z) = (*x3, 4);
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:48:18
@@ -129,6 +137,7 @@ LL | fn g1<X: ?Sized>(x: X) {}
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:50:22
@@ -140,6 +149,7 @@ LL | fn g2<X: ?Sized + T>(x: X) {}
    = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: all local variables must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
 error: aborting due to 13 previous errors