about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff43
-rw-r--r--tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff39
-rw-r--r--tests/mir-opt/const_prop/offset_of.rs49
-rw-r--r--tests/ui/lint/dead-code/offset-of-correct-param-env.rs42
-rw-r--r--tests/ui/lint/dead-code/offset-of.rs44
-rw-r--r--tests/ui/lint/dead-code/offset-of.stderr50
-rw-r--r--tests/ui/macros/user-defined-macro-rules.rs (renamed from tests/ui/user-defined-macro-rules.rs)0
-rw-r--r--tests/ui/offset-of/auxiliary/offset-of-staged-api.rs33
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.rs9
-rw-r--r--tests/ui/offset-of/offset-of-arg-count.stderr20
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.rs33
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr27
-rw-r--r--tests/ui/offset-of/offset-of-enum.rs13
-rw-r--r--tests/ui/offset-of/offset-of-enum.stderr19
-rw-r--r--tests/ui/offset-of/offset-of-private.rs16
-rw-r--r--tests/ui/offset-of/offset-of-private.stderr9
-rw-r--r--tests/ui/offset-of/offset-of-unstable-with-feature.rs20
-rw-r--r--tests/ui/offset-of/offset-of-unstable.rs31
-rw-r--r--tests/ui/offset-of/offset-of-unstable.stderr79
19 files changed, 576 insertions, 0 deletions
diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
new file mode 100644
index 00000000000..4e2f1b39d2b
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff
@@ -0,0 +1,43 @@
+- // MIR for `concrete` before ConstProp
++ // MIR for `concrete` after ConstProp
+  
+  fn concrete() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/offset_of.rs:+0:15: +0:15
+      let _1: usize;                       // in scope 0 at $DIR/offset_of.rs:+1:9: +1:10
+      scope 1 {
+          debug x => _1;                   // in scope 1 at $DIR/offset_of.rs:+1:9: +1:10
+          let _2: usize;                   // in scope 1 at $DIR/offset_of.rs:+2:9: +2:10
+          scope 2 {
+              debug y => _2;               // in scope 2 at $DIR/offset_of.rs:+2:9: +2:10
+              let _3: usize;               // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+              scope 3 {
+                  debug z0 => _3;          // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11
+                  let _4: usize;           // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+                  scope 4 {
+                      debug z1 => _4;      // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:10
+-         _1 = OffsetOf(Alpha, [0]);       // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
++         _1 = const 4_usize;              // scope 0 at $DIR/offset_of.rs:+1:13: +1:33
+          StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:10
+-         _2 = OffsetOf(Alpha, [1]);       // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
++         _2 = const 0_usize;              // scope 1 at $DIR/offset_of.rs:+2:13: +2:33
+          StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+-         _3 = OffsetOf(Alpha, [2, 0]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
++         _3 = const 2_usize;              // scope 2 at $DIR/offset_of.rs:+3:14: +3:36
+          StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+-         _4 = OffsetOf(Alpha, [2, 1]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
++         _4 = const 3_usize;              // scope 3 at $DIR/offset_of.rs:+4:14: +4:36
+          StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/offset_of.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/offset_of.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
new file mode 100644
index 00000000000..5c6cb47089e
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff
@@ -0,0 +1,39 @@
+- // MIR for `generic` before ConstProp
++ // MIR for `generic` after ConstProp
+  
+  fn generic() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/offset_of.rs:+0:17: +0:17
+      let _1: usize;                       // in scope 0 at $DIR/offset_of.rs:+1:9: +1:11
+      scope 1 {
+          debug gx => _1;                  // in scope 1 at $DIR/offset_of.rs:+1:9: +1:11
+          let _2: usize;                   // in scope 1 at $DIR/offset_of.rs:+2:9: +2:11
+          scope 2 {
+              debug gy => _2;              // in scope 2 at $DIR/offset_of.rs:+2:9: +2:11
+              let _3: usize;               // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+              scope 3 {
+                  debug dx => _3;          // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11
+                  let _4: usize;           // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+                  scope 4 {
+                      debug dy => _4;      // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/offset_of.rs:+1:9: +1:11
+          _1 = OffsetOf(Gamma<T>, [0]);    // scope 0 at $DIR/offset_of.rs:+1:14: +1:37
+          StorageLive(_2);                 // scope 1 at $DIR/offset_of.rs:+2:9: +2:11
+          _2 = OffsetOf(Gamma<T>, [1]);    // scope 1 at $DIR/offset_of.rs:+2:14: +2:37
+          StorageLive(_3);                 // scope 2 at $DIR/offset_of.rs:+3:9: +3:11
+          _3 = OffsetOf(Delta<T>, [1]);    // scope 2 at $DIR/offset_of.rs:+3:14: +3:37
+          StorageLive(_4);                 // scope 3 at $DIR/offset_of.rs:+4:9: +4:11
+          _4 = OffsetOf(Delta<T>, [2]);    // scope 3 at $DIR/offset_of.rs:+4:14: +4:37
+          StorageDead(_4);                 // scope 3 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_3);                 // scope 2 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_2);                 // scope 1 at $DIR/offset_of.rs:+5:1: +5:2
+          StorageDead(_1);                 // scope 0 at $DIR/offset_of.rs:+5:1: +5:2
+          return;                          // scope 0 at $DIR/offset_of.rs:+5:2: +5:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs
new file mode 100644
index 00000000000..eabdf848079
--- /dev/null
+++ b/tests/mir-opt/const_prop/offset_of.rs
@@ -0,0 +1,49 @@
+// unit-test
+// compile-flags: -O
+
+#![feature(offset_of)]
+
+use std::marker::PhantomData;
+use std::mem::offset_of;
+
+struct Alpha {
+    x: u8,
+    y: u16,
+    z: Beta,
+}
+
+struct Beta(u8, u8);
+
+struct Gamma<T> {
+    x: u8,
+    y: u16,
+    _t: T,
+}
+
+#[repr(C)]
+struct Delta<T> {
+    _phantom: PhantomData<T>,
+    x: u8,
+    y: u16,
+}
+
+// EMIT_MIR offset_of.concrete.ConstProp.diff
+fn concrete() {
+    let x = offset_of!(Alpha, x);
+    let y = offset_of!(Alpha, y);
+    let z0 = offset_of!(Alpha, z.0);
+    let z1 = offset_of!(Alpha, z.1);
+}
+
+// EMIT_MIR offset_of.generic.ConstProp.diff
+fn generic<T>() {
+    let gx = offset_of!(Gamma<T>, x);
+    let gy = offset_of!(Gamma<T>, y);
+    let dx = offset_of!(Delta<T>, x);
+    let dy = offset_of!(Delta<T>, y);
+}
+
+fn main() {
+    concrete();
+    generic::<()>();
+}
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
new file mode 100644
index 00000000000..2c6fcef2500
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs
@@ -0,0 +1,42 @@
+// check-pass
+
+#![feature(offset_of)]
+#![deny(dead_code)]
+
+// This struct contains a projection that can only be normalized after getting the field type.
+struct A<T: Project> {
+    a: <T as Project>::EquateParamTo,
+}
+
+// This is the inner struct that we want to get.
+struct MyFieldIsNotDead {
+    not_dead: u8,
+}
+
+// These are some helpers.
+// Inside the param env of `test`, we want to make it so that it considers T=MyFieldIsNotDead.
+struct GenericIsEqual<T>(T);
+trait Project {
+    type EquateParamTo;
+}
+impl<T> Project for GenericIsEqual<T> {
+    type EquateParamTo = T;
+}
+
+fn test<T>() -> usize
+where
+    GenericIsEqual<T>: Project<EquateParamTo = MyFieldIsNotDead>,
+{
+    // The first field of the A that we construct here is
+    // `<GenericIsEqual<T>> as Project>::EquateParamTo`.
+    // Typeck normalizes this and figures that the not_dead field is totally fine and accessible.
+    // 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.
+    // If we use the wrong param env, the lint will ICE.
+    std::mem::offset_of!(A<GenericIsEqual<T>>, a.not_dead)
+}
+
+fn main() {
+    test::<MyFieldIsNotDead>();
+}
diff --git a/tests/ui/lint/dead-code/offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs
new file mode 100644
index 00000000000..da91de3862f
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of.rs
@@ -0,0 +1,44 @@
+#![feature(offset_of)]
+#![deny(dead_code)]
+
+use std::mem::offset_of;
+
+struct Alpha {
+    a: (),
+    b: (), //~ ERROR field `b` is never read
+    c: Beta,
+}
+
+struct Beta {
+    a: (), //~ ERROR field `a` is never read
+    b: (),
+}
+
+struct Gamma {
+    a: (), //~ ERROR field `a` is never read
+    b: (),
+}
+
+struct Delta {
+    a: (),
+    b: (), //~ ERROR field `b` is never read
+}
+
+trait Trait {
+    type Assoc;
+}
+impl Trait for () {
+    type Assoc = Delta;
+}
+
+struct Project<T: Trait> {
+    a: u8, //~ ERROR field `a` is never read
+    b: <T as Trait>::Assoc,
+}
+
+fn main() {
+    offset_of!(Alpha, a);
+    offset_of!(Alpha, c.b);
+    offset_of!((Gamma,), 0.b);
+    offset_of!(Project::<()>, b.a);
+}
diff --git a/tests/ui/lint/dead-code/offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr
new file mode 100644
index 00000000000..ed2916461cd
--- /dev/null
+++ b/tests/ui/lint/dead-code/offset-of.stderr
@@ -0,0 +1,50 @@
+error: field `b` is never read
+  --> $DIR/offset-of.rs:8:5
+   |
+LL | struct Alpha {
+   |        ----- field in this struct
+LL |     a: (),
+LL |     b: (),
+   |     ^
+   |
+note: the lint level is defined here
+  --> $DIR/offset-of.rs:2:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:13:5
+   |
+LL | struct Beta {
+   |        ---- field in this struct
+LL |     a: (),
+   |     ^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:18:5
+   |
+LL | struct Gamma {
+   |        ----- field in this struct
+LL |     a: (),
+   |     ^
+
+error: field `b` is never read
+  --> $DIR/offset-of.rs:24:5
+   |
+LL | struct Delta {
+   |        ----- field in this struct
+LL |     a: (),
+LL |     b: (),
+   |     ^
+
+error: field `a` is never read
+  --> $DIR/offset-of.rs:35:5
+   |
+LL | struct Project<T: Trait> {
+   |        ------- field in this struct
+LL |     a: u8,
+   |     ^
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/user-defined-macro-rules.rs b/tests/ui/macros/user-defined-macro-rules.rs
index 09e071ec454..09e071ec454 100644
--- a/tests/ui/user-defined-macro-rules.rs
+++ b/tests/ui/macros/user-defined-macro-rules.rs
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-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs
new file mode 100644
index 00000000000..163b07454ec
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-arg-count.rs
@@ -0,0 +1,9 @@
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+fn main() {
+    offset_of!(NotEnoughArguments); //~ ERROR expected one of
+    offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments
+    offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments
+}
diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr
new file mode 100644
index 00000000000..ebecc982c51
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-arg-count.stderr
@@ -0,0 +1,20 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>`
+  --> $DIR/offset-of-arg-count.rs:6:16
+   |
+LL |     offset_of!(NotEnoughArguments);
+   |                ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<`
+
+error: expected 2 arguments
+  --> $DIR/offset-of-arg-count.rs:7:5
+   |
+LL |     offset_of!(NotEnoughArgumentsWithAComma, );
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected 2 arguments
+  --> $DIR/offset-of-arg-count.rs:8:5
+   |
+LL |     offset_of!(Container, field, too many arguments);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs
new file mode 100644
index 00000000000..a0269ca2d12
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-dst-field.rs
@@ -0,0 +1,33 @@
+#![feature(offset_of, extern_types)]
+
+use std::mem::offset_of;
+
+struct Alpha {
+    x: u8,
+    y: u16,
+    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!(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
new file mode 100644
index 00000000000..8e88015b07a
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:30:5
+   |
+LL |     offset_of!(Alpha, z);
+   |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+
+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-private.rs b/tests/ui/offset-of/offset-of-private.rs
new file mode 100644
index 00000000000..0291b7825ca
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-private.rs
@@ -0,0 +1,16 @@
+#![feature(offset_of)]
+
+use std::mem::offset_of;
+
+mod m {
+    #[repr(C)]
+    pub struct Foo {
+        pub public: u8,
+        private: u8,
+    }
+}
+
+fn main() {
+    offset_of!(m::Foo, public);
+    offset_of!(m::Foo, private); //~ ERROR field `private` of struct `Foo` is private
+}
diff --git a/tests/ui/offset-of/offset-of-private.stderr b/tests/ui/offset-of/offset-of-private.stderr
new file mode 100644
index 00000000000..8a186dd5a02
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-private.stderr
@@ -0,0 +1,9 @@
+error[E0616]: field `private` of struct `Foo` is private
+  --> $DIR/offset-of-private.rs:15:24
+   |
+LL |     offset_of!(m::Foo, private);
+   |                        ^^^^^^^ private field
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0616`.
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`.