Skip to content

Check the type of statics and constants for Sizedness #55004

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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