diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 2351406ddd2..7f033816901 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -388,6 +388,115 @@ fn offset_of() { assert!(offset_of!((u8, u16), 1) <= size_of::<(u8, u16)>() - 2); } +#[test] +#[cfg(not(bootstrap))] +fn offset_of_union() { + #[repr(C)] + union Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + #[derive(Copy, Clone)] + struct Bar(u8, u8); + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 0); + assert_eq!(offset_of!(Foo, z.0), 0); + assert_eq!(offset_of!(Foo, z.1), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_dst() { + #[repr(C)] + struct Alpha { + x: u8, + y: u16, + z: [u8], + } + + trait Trait {} + + #[repr(C)] + struct Beta { + x: u8, + y: u16, + z: dyn Trait, + } + + extern "C" { + type Extern; + } + + #[repr(C)] + struct Gamma { + x: u8, + y: u16, + z: Extern, + } + + assert_eq!(offset_of!(Alpha, x), 0); + assert_eq!(offset_of!(Alpha, y), 2); + + assert_eq!(offset_of!(Beta, x), 0); + assert_eq!(offset_of!(Beta, y), 2); + + assert_eq!(offset_of!(Gamma, x), 0); + assert_eq!(offset_of!(Gamma, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_packed() { + #[repr(C, packed)] + struct Foo { + x: u8, + y: u16, + } + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_projection() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + trait Projector { + type Type; + } + + impl Projector for () { + type Type = Foo; + } + + assert_eq!(offset_of!(<() as Projector>::Type, x), 0); + assert_eq!(offset_of!(<() as Projector>::Type, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_alias() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + type Bar = Foo; + + assert_eq!(offset_of!(Bar, x), 0); + assert_eq!(offset_of!(Bar, y), 2); +} + #[test] #[cfg(not(bootstrap))] fn const_offset_of() { @@ -425,20 +534,6 @@ fn offset_of_without_const_promotion() { inner::<()>(); } -#[test] -#[cfg(not(bootstrap))] -fn offset_of_dst() { - #[repr(C)] - struct Foo { - x: u8, - y: u16, - slice: [u8], - } - - assert_eq!(offset_of!(Foo, x), 0); - assert_eq!(offset_of!(Foo, y), 2); -} - #[test] #[cfg(not(bootstrap))] fn offset_of_addr() { diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs index ae5d5a68e6a..2c6fcef2500 100644 --- a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs +++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs @@ -33,7 +33,7 @@ where // But importantly, the normalization ends up with T, which, as we've declared in our param // env is MyFieldDead. When we're in the param env of the `a` field, the where bound above // is not in scope, so we don't know what T is - it's generic. - // We cannot access a field on T. Boom! + // If we use the wrong param env, the lint will ICE. std::mem::offset_of!(A>, a.not_dead) } diff --git a/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs new file mode 100644 index 00000000000..088086cc580 --- /dev/null +++ b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs @@ -0,0 +1,33 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.0")] + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct Unstable { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct Stable { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableField { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableFieldType { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: Unstable, +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableWithStableFieldType { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: Stable, +} diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index b741cad05c2..a0269ca2d12 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,14 +1,33 @@ -#![feature(offset_of)] +#![feature(offset_of, extern_types)] use std::mem::offset_of; -#[repr(C)] -struct Foo { +struct Alpha { x: u8, y: u16, - slice: [u8], + z: [u8], +} + +trait Trait {} + +struct Beta { + x: u8, + y: u16, + z: dyn Trait, +} + +extern { + type Extern; +} + +struct Gamma { + x: u8, + y: u16, + z: Extern, } fn main() { - offset_of!(Foo, slice); //~ ERROR the size for values of type + offset_of!(Alpha, z); //~ ERROR the size for values of type + offset_of!(Beta, z); //~ ERROR the size for values of type + offset_of!(Gamma, z); //~ ERROR the size for values of type } diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index a490f384da5..8e88015b07a 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -1,11 +1,27 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:13:5 + --> $DIR/offset-of-dst-field.rs:30:5 | -LL | offset_of!(Foo, slice); - | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time +LL | offset_of!(Alpha, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -error: aborting due to previous error +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:31:5 + | +LL | offset_of!(Beta, z); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` + +error[E0277]: the size for values of type `Extern` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:32:5 + | +LL | offset_of!(Gamma, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `Extern` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs new file mode 100644 index 00000000000..d73505821ff --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -0,0 +1,13 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +enum Alpha { + One(u8), + Two(u8), +} + +fn main() { + offset_of!(Alpha::One, 0); //~ ERROR expected type, found variant `Alpha::One` + offset_of!(Alpha, Two.0); //~ ERROR no field `Two` on type `Alpha` +} diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr new file mode 100644 index 00000000000..6958d199fbd --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -0,0 +1,19 @@ +error[E0573]: expected type, found variant `Alpha::One` + --> $DIR/offset-of-enum.rs:11:16 + | +LL | offset_of!(Alpha::One, 0); + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Alpha` + +error[E0609]: no field `Two` on type `Alpha` + --> $DIR/offset-of-enum.rs:12:23 + | +LL | offset_of!(Alpha, Two.0); + | ^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0573, E0609. +For more information about an error, try `rustc --explain E0573`. diff --git a/tests/ui/offset-of/offset-of-unstable-with-feature.rs b/tests/ui/offset-of/offset-of-unstable-with-feature.rs new file mode 100644 index 00000000000..7d2eb46c056 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable-with-feature.rs @@ -0,0 +1,20 @@ +// check-pass +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of, unstable_test_feature)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!(Unstable, unstable); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); + offset_of!(UnstableWithStableFieldType, unstable); + offset_of!(UnstableWithStableFieldType, unstable.stable); +} diff --git a/tests/ui/offset-of/offset-of-unstable.rs b/tests/ui/offset-of/offset-of-unstable.rs new file mode 100644 index 00000000000..1e19f2091f2 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.rs @@ -0,0 +1,31 @@ +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!( + //~^ ERROR use of unstable library feature + Unstable, //~ ERROR use of unstable library feature + unstable + ); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); //~ ERROR use of unstable library feature + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); //~ ERROR use of unstable library feature + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable + ); + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable.stable + ); +} diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr new file mode 100644 index 00000000000..25811a061d7 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.stderr @@ -0,0 +1,79 @@ +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:14:9 + | +LL | Unstable, + | ^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:23:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:28:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:12:5 + | +LL | / offset_of!( +LL | | +LL | | Unstable, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:18:5 + | +LL | offset_of!(StableWithUnstableField, unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:20:5 + | +LL | offset_of!(StableWithUnstableFieldType, stable.unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:21:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:26:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable.stable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0658`.