Skip to content

Commit

Permalink
Rollup merge of #55004 - oli-obk:sized_static, r=cramertj
Browse files Browse the repository at this point in the history
Check the type of statics and constants for `Sized`ness

fixes #54410
  • Loading branch information
kennytm committed Oct 18, 2018
2 parents cb9f6be + 10a01c1 commit 1babdd6
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 77 deletions.
38 changes: 26 additions & 12 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
});
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-array-oob.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/const-eval-overflow-4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
15 changes: 6 additions & 9 deletions src/test/ui/consts/const-eval/const-eval-overflow-4.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
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]
| ^^^^^^^^^^^^^^^^^^^^^
|
= 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

Expand Down
20 changes: 8 additions & 12 deletions src/test/ui/consts/const-unsized.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/infinite/infinite-recursion-const-fn.stderr
Original file line number Diff line number Diff line change
@@ -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() }
| ---
Expand Down Expand Up @@ -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`

Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/issues/issue-24446.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}
31 changes: 5 additions & 26 deletions src/test/ui/issues/issue-24446.stderr
Original file line number Diff line number Diff line change
@@ -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`.
8 changes: 8 additions & 0 deletions src/test/ui/issues/issue-54410.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extern "C" {
pub static mut symbol: [i8];
//~^ ERROR the size for values of type `[i8]` cannot be known at compilation time
}

fn main() {
println!("{:p}", unsafe { &symbol });
}
12 changes: 12 additions & 0 deletions src/test/ui/issues/issue-54410.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
--> $DIR/issue-54410.rs:2:28
|
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>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
12 changes: 12 additions & 0 deletions src/test/ui/static_sized_requirement.rs
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/wf/wf-const-type.stderr
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/wf/wf-static-type.stderr
Original file line number Diff line number Diff line change
@@ -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`
Expand Down

0 comments on commit 1babdd6

Please sign in to comment.