From 8180e1b54c1f7457c258701287bcbbf32170a743 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Thu, 11 Oct 2018 18:02:00 +0200
Subject: [PATCH 1/4] Check the type of statics and constants for `Sized`ness

---
 src/librustc_typeck/check/wfcheck.rs          | 38 +++++++++++++------
 src/test/ui/consts/const-array-oob.stderr     |  4 +-
 .../const-eval/const-eval-overflow-4.rs       |  2 +-
 .../const-eval/const-eval-overflow-4.stderr   | 15 +++-----
 src/test/ui/consts/const-unsized.stderr       | 20 ++++------
 .../infinite-recursion-const-fn.stderr        |  4 +-
 src/test/ui/issues/issue-24446.rs             |  3 +-
 src/test/ui/issues/issue-24446.stderr         | 31 +++------------
 src/test/ui/issues/issue-54410.rs             |  9 +++++
 src/test/ui/issues/issue-54410.stderr         | 12 ++++++
 ...-bounds-on-structs-and-enums-static.stderr |  9 ++---
 src/test/ui/wf/wf-const-type.stderr           |  4 +-
 src/test/ui/wf/wf-static-type.stderr          |  4 +-
 13 files changed, 79 insertions(+), 76 deletions(-)
 create mode 100644 src/test/ui/issues/issue-54410.rs
 create mode 100644 src/test/ui/issues/issue-54410.stderr

diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index cc1906d91d4c9..016ea5cba6609 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -118,12 +118,17 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
         hir::ItemKind::Fn(..) => {
             check_item_fn(tcx, item);
         }
-        hir::ItemKind::Static(..) => {
-            check_item_type(tcx, item);
+        hir::ItemKind::Static(ref ty, ..) => {
+            check_item_type(tcx, item.id, ty.span);
         }
-        hir::ItemKind::Const(..) => {
-            check_item_type(tcx, item);
+        hir::ItemKind::Const(ref ty, ..) => {
+            check_item_type(tcx, item.id, ty.span);
         }
+        hir::ItemKind::ForeignMod(ref module) => for it in module.items.iter() {
+            if let hir::ForeignItemKind::Static(ref ty, ..) = it.node {
+                check_item_type(tcx, it.id, ty.span);
+            }
+        },
         hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
             check_type_defn(tcx, item, false, |fcx| {
                 vec![fcx.non_enum_variant(struct_def)]
@@ -335,14 +340,23 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     })
 }
 
-fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
-    debug!("check_item_type: {:?}", item);
-
-    for_item(tcx, item).with_fcx(|fcx, _this| {
-        let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id));
-        let item_ty = fcx.normalize_associated_types_in(item.span, &ty);
-
-        fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation);
+fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId, ty_span: Span) {
+    debug!("check_item_type: {:?}", item_id);
+
+    for_id(tcx, item_id, ty_span).with_fcx(|fcx, _this| {
+        let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item_id));
+        let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
+
+        fcx.register_wf_obligation(item_ty, ty_span, ObligationCauseCode::MiscObligation);
+        fcx.register_bound(
+            item_ty,
+            fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+            traits::ObligationCause::new(
+                ty_span,
+                fcx.body_id,
+                traits::MiscObligation,
+            ),
+        );
 
         vec![] // no implied bounds in a const etc
     });
diff --git a/src/test/ui/consts/const-array-oob.stderr b/src/test/ui/consts/const-array-oob.stderr
index 09e4918bf6eed..19ec9a4aa1745 100644
--- a/src/test/ui/consts/const-array-oob.stderr
+++ b/src/test/ui/consts/const-array-oob.stderr
@@ -7,10 +7,10 @@ LL | const BLUB: [u32; FOO[4]] = [5, 6];
    = note: #[deny(const_err)] on by default
 
 error[E0080]: could not evaluate constant expression
-  --> $DIR/const-array-oob.rs:18:1
+  --> $DIR/const-array-oob.rs:18:13
    |
 LL | const BLUB: [u32; FOO[4]] = [5, 6];
-   | ^^^^^^^^^^^^^^^^^^------^^^^^^^^^^^
+   |             ^^^^^^------^
    |                   |
    |                   index out of bounds: the len is 3 but the index is 4
 
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-4.rs b/src/test/ui/consts/const-eval/const-eval-overflow-4.rs
index 9fc31b7c72781..e9fc8ec0c374e 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-4.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-4.rs
@@ -20,9 +20,9 @@ use std::{i8, i16, i32, i64, isize};
 use std::{u8, u16, u32, u64, usize};
 
 const A_I8_T
-    //~^ ERROR could not evaluate constant expression
     : [u32; (i8::MAX as i8 + 1i8) as usize]
     //~^ ERROR attempt to add with overflow
+    //~| ERROR could not evaluate constant expression
     = [0; (i8::MAX as usize) + 1];
 
 fn main() {
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-4.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-4.stderr
index 058c8730d7c9e..b12aa032b6070 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-4.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-4.stderr
@@ -1,5 +1,5 @@
 error: attempt to add with overflow
-  --> $DIR/const-eval-overflow-4.rs:24:13
+  --> $DIR/const-eval-overflow-4.rs:23:13
    |
 LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
    |             ^^^^^^^^^^^^^^^^^^^^^
@@ -7,15 +7,12 @@ LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
    = note: #[deny(const_err)] on by default
 
 error[E0080]: could not evaluate constant expression
-  --> $DIR/const-eval-overflow-4.rs:22:1
+  --> $DIR/const-eval-overflow-4.rs:23:7
    |
-LL | / const A_I8_T
-LL | |     //~^ ERROR could not evaluate constant expression
-LL | |     : [u32; (i8::MAX as i8 + 1i8) as usize]
-   | |             --------------------- attempt to add with overflow
-LL | |     //~^ ERROR attempt to add with overflow
-LL | |     = [0; (i8::MAX as usize) + 1];
-   | |__________________________________^
+LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
+   |       ^^^^^^---------------------^^^^^^^^^^
+   |             |
+   |             attempt to add with overflow
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-unsized.stderr b/src/test/ui/consts/const-unsized.stderr
index 83d23bcba0493..8671e609ac8e5 100644
--- a/src/test/ui/consts/const-unsized.stderr
+++ b/src/test/ui/consts/const-unsized.stderr
@@ -1,42 +1,38 @@
 error[E0277]: the size for values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:13:29
+  --> $DIR/const-unsized.rs:13:16
    |
 LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + '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: constant expressions must have a statically known size
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:16:24
+  --> $DIR/const-unsized.rs:16:18
    |
 LL | const CONST_FOO: str = *"foo";
-   |                        ^^^^^^ doesn't have a size known at compile-time
+   |                  ^^^ doesn't have a size known at compile-time
    |
    = 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: constant expressions must have a statically known size
 
 error[E0277]: the size for values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:19:31
+  --> $DIR/const-unsized.rs:19:18
    |
 LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
-   |                               ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                  ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + '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: constant expressions must have a statically known size
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
-  --> $DIR/const-unsized.rs:22:26
+  --> $DIR/const-unsized.rs:22:20
    |
 LL | static STATIC_BAR: str = *"bar";
-   |                          ^^^^^^ doesn't have a size known at compile-time
+   |                    ^^^ doesn't have a size known at compile-time
    |
    = 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: constant expressions must have a statically known size
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr
index 579cc6bd548f9..c77452d9abe20 100644
--- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr
+++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr
@@ -1,5 +1,5 @@
 error[E0080]: could not evaluate constant expression
-  --> $DIR/infinite-recursion-const-fn.rs:15:1
+  --> $DIR/infinite-recursion-const-fn.rs:15:12
    |
 LL | const fn a() -> usize { b() }
    |                         ---
@@ -59,7 +59,7 @@ LL | const fn b() -> usize { a() }
    |                         inside call to `a`
    |                         inside call to `a`
 LL | const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression
-   | ^^^^^^^^^^^^^^^^^---^^^^^^^^^^^
+   |            ^^^^^^---^
    |                  |
    |                  inside call to `a`
 
diff --git a/src/test/ui/issues/issue-24446.rs b/src/test/ui/issues/issue-24446.rs
index a9c7978642d5f..7c44319db0db2 100644
--- a/src/test/ui/issues/issue-24446.rs
+++ b/src/test/ui/issues/issue-24446.rs
@@ -10,8 +10,7 @@
 
 fn main() {
     static foo: Fn() -> u32 = || -> u32 {
-        //~^ ERROR mismatched types
-        //~| ERROR the size for values of type
+        //~^ ERROR the size for values of type
         0
     };
 }
diff --git a/src/test/ui/issues/issue-24446.stderr b/src/test/ui/issues/issue-24446.stderr
index 3c42462743700..d4921443cad76 100644
--- a/src/test/ui/issues/issue-24446.stderr
+++ b/src/test/ui/issues/issue-24446.stderr
@@ -1,33 +1,12 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-24446.rs:12:31
-   |
-LL |       static foo: Fn() -> u32 = || -> u32 {
-   |  _______________________________^
-LL | |         //~^ ERROR mismatched types
-LL | |         //~| ERROR the size for values of type
-LL | |         0
-LL | |     };
-   | |_____^ expected trait std::ops::Fn, found closure
-   |
-   = note: expected type `(dyn std::ops::Fn() -> u32 + 'static)`
-              found type `[closure@$DIR/issue-24446.rs:12:31: 16:6]`
-
 error[E0277]: the size for values of type `(dyn std::ops::Fn() -> u32 + 'static)` cannot be known at compilation time
-  --> $DIR/issue-24446.rs:12:31
+  --> $DIR/issue-24446.rs:12:17
    |
-LL |       static foo: Fn() -> u32 = || -> u32 {
-   |  _______________________________^
-LL | |         //~^ ERROR mismatched types
-LL | |         //~| ERROR the size for values of type
-LL | |         0
-LL | |     };
-   | |_____^ doesn't have a size known at compile-time
+LL |     static foo: Fn() -> u32 = || -> u32 {
+   |                 ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn() -> u32 + '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: constant expressions must have a statically known size
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors occurred: E0277, E0308.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-54410.rs b/src/test/ui/issues/issue-54410.rs
new file mode 100644
index 0000000000000..192b97a167728
--- /dev/null
+++ b/src/test/ui/issues/issue-54410.rs
@@ -0,0 +1,9 @@
+use std::os::raw::c_char;
+extern "C" {
+    pub static mut symbol: [c_char];
+    //~^ ERROR the size for values of type `[i8]` cannot be known at compilation time
+}
+
+fn main() {
+    println!("{:p}", unsafe { &symbol });
+}
diff --git a/src/test/ui/issues/issue-54410.stderr b/src/test/ui/issues/issue-54410.stderr
new file mode 100644
index 0000000000000..0c40c6384a470
--- /dev/null
+++ b/src/test/ui/issues/issue-54410.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
+  --> $DIR/issue-54410.rs:3:28
+   |
+LL |     pub static mut symbol: [c_char];
+   |                            ^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `[i8]`
+   = 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>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
index 28d4257a9fba9..5145ba1881d5b 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
@@ -1,11 +1,8 @@
 error[E0277]: the trait bound `usize: Trait` is not satisfied
-  --> $DIR/trait-bounds-on-structs-and-enums-static.rs:19:1
+  --> $DIR/trait-bounds-on-structs-and-enums-static.rs:19:11
    |
-LL | / static X: Foo<usize> = Foo {
-LL | | //~^ ERROR E0277
-LL | |     x: 1,
-LL | | };
-   | |__^ the trait `Trait` is not implemented for `usize`
+LL | static X: Foo<usize> = Foo {
+   |           ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
    |
 note: required by `Foo`
   --> $DIR/trait-bounds-on-structs-and-enums-static.rs:15:1
diff --git a/src/test/ui/wf/wf-const-type.stderr b/src/test/ui/wf/wf-const-type.stderr
index 1c07824ef77a2..78e831ef880fc 100644
--- a/src/test/ui/wf/wf-const-type.stderr
+++ b/src/test/ui/wf/wf-const-type.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `NotCopy: std::marker::Copy` is not satisfied
-  --> $DIR/wf-const-type.rs:20:1
+  --> $DIR/wf-const-type.rs:20:12
    |
 LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
+   |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `std::option::Option<NotCopy>`
 note: required by `IsCopy`
diff --git a/src/test/ui/wf/wf-static-type.stderr b/src/test/ui/wf/wf-static-type.stderr
index f76444cfe1fef..c9656d8654655 100644
--- a/src/test/ui/wf/wf-static-type.stderr
+++ b/src/test/ui/wf/wf-static-type.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `NotCopy: std::marker::Copy` is not satisfied
-  --> $DIR/wf-static-type.rs:20:1
+  --> $DIR/wf-static-type.rs:20:13
    |
 LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `std::option::Option<NotCopy>`
 note: required by `IsCopy`

From 4dcf49121cf4b195929099cedac19a489d403eb4 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Sun, 14 Oct 2018 17:45:35 +0200
Subject: [PATCH 2/4] Use platform independent types

---
 src/test/ui/issues/issue-54410.rs     | 3 +--
 src/test/ui/issues/issue-54410.stderr | 6 +++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/test/ui/issues/issue-54410.rs b/src/test/ui/issues/issue-54410.rs
index 192b97a167728..e3e8ca985b970 100644
--- a/src/test/ui/issues/issue-54410.rs
+++ b/src/test/ui/issues/issue-54410.rs
@@ -1,6 +1,5 @@
-use std::os::raw::c_char;
 extern "C" {
-    pub static mut symbol: [c_char];
+    pub static mut symbol: [i8];
     //~^ ERROR the size for values of type `[i8]` cannot be known at compilation time
 }
 
diff --git a/src/test/ui/issues/issue-54410.stderr b/src/test/ui/issues/issue-54410.stderr
index 0c40c6384a470..ae6888f067e68 100644
--- a/src/test/ui/issues/issue-54410.stderr
+++ b/src/test/ui/issues/issue-54410.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
-  --> $DIR/issue-54410.rs:3:28
+  --> $DIR/issue-54410.rs:2:28
    |
-LL |     pub static mut symbol: [c_char];
-   |                            ^^^^^^^^ doesn't have a size known at compile-time
+LL |     pub static mut symbol: [i8];
+   |                            ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[i8]`
    = 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>

From fbbc73969b60d1ce58fe028daa8924ab56465928 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Mon, 15 Oct 2018 20:48:25 +0200
Subject: [PATCH 3/4] Add test for no_core statics

---
 src/test/ui/static_sized_requirement.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 src/test/ui/static_sized_requirement.rs

diff --git a/src/test/ui/static_sized_requirement.rs b/src/test/ui/static_sized_requirement.rs
new file mode 100644
index 0000000000000..0ee0637232ca4
--- /dev/null
+++ b/src/test/ui/static_sized_requirement.rs
@@ -0,0 +1,12 @@
+// compile-pass
+
+#![feature(no_core, lang_items)]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+extern {
+    pub static A: u32;
+}

From 10a01c1bcd18c33a817751858ebcc022437917ef Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Tue, 16 Oct 2018 17:00:33 +0200
Subject: [PATCH 4/4] Update cargo submodule

---
 src/tools/cargo | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/cargo b/src/tools/cargo
index 5dbac98885199..09ce4b519535c 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 5dbac98885199bbd7c0f189d7405b5523434d1e3
+Subproject commit 09ce4b519535c77d17b818b6dc0b72c6668642c1