]> git.lizzy.rs Git - rust.git/commitdiff
Allow #[repr(align(x))] on enums (#57996)
authorNiklas Fiekas <niklas.fiekas@backscattering.de>
Wed, 30 Jan 2019 13:14:16 +0000 (14:14 +0100)
committerNiklas Fiekas <niklas.fiekas@backscattering.de>
Wed, 30 Jan 2019 13:15:38 +0000 (14:15 +0100)
src/doc/unstable-book/src/language-features/repr-align-enum.md [new file with mode: 0644]
src/librustc/hir/check_attr.rs
src/libsyntax/feature_gate.rs
src/test/run-pass/structs-enums/align-enum.rs [new file with mode: 0644]
src/test/ui/attr-usage-repr.rs
src/test/ui/attr-usage-repr.stderr
src/test/ui/feature-gates/feature-gate-repr_align_enum.rs [new file with mode: 0644]
src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr [new file with mode: 0644]

diff --git a/src/doc/unstable-book/src/language-features/repr-align-enum.md b/src/doc/unstable-book/src/language-features/repr-align-enum.md
new file mode 100644 (file)
index 0000000..1fd9bd2
--- /dev/null
@@ -0,0 +1,26 @@
+# `repr_align_enum`
+
+The tracking issue for this feature is: [#57996]
+
+[#57996]: https://github.com/rust-lang/rust/issues/57996
+
+------------------------
+
+The `repr_align_enum` feature allows using the `#[repr(align(x))]` attribute
+on enums, similarly to structs.
+
+# Examples
+
+```rust
+#![feature(repr_align_enum)]
+
+#[repr(align(8))]
+enum Aligned {
+    Foo,
+    Bar { value: u32 },
+}
+
+fn main() {
+    assert_eq!(std::mem::align_of::<Aligned>(), 8);
+}
+```
index df111b2be319f8bab3e36644215a4cbae44fb1a3..9fac88fbbe9ab8c3b07f11f803ed90105e0e5695 100644 (file)
@@ -187,8 +187,8 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
             };
 
             let (article, allowed_targets) = match &*name.as_str() {
-                "C" => {
-                    is_c = true;
+                "C" | "align" => {
+                    is_c |= name == "C";
                     if target != Target::Struct &&
                             target != Target::Union &&
                             target != Target::Enum {
@@ -213,14 +213,6 @@ fn check_repr(&self, item: &hir::Item, target: Target) {
                         continue
                     }
                 }
-                "align" => {
-                    if target != Target::Struct &&
-                            target != Target::Union {
-                        ("a", "struct or union")
-                    } else {
-                        continue
-                    }
-                }
                 "transparent" => {
                     is_transparent = true;
                     if target != Target::Struct {
index 2820924824697e4fd27d732d0067075c912d4568..218a3f52ee0b23e9ca157bf679c21ea8c250c11d 100644 (file)
@@ -461,6 +461,9 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
 
     // #[optimize(X)]
     (active, optimize_attribute, "1.34.0", Some(54882), None),
+
+    // #[repr(align(X))] on enums
+    (active, repr_align_enum, "1.34.0", Some(57996), None),
 );
 
 declare_features! (
@@ -1697,6 +1700,17 @@ fn visit_item(&mut self, i: &'a ast::Item) {
                 }
             }
 
+            ast::ItemKind::Enum(..) => {
+                for attr in attr::filter_by_name(&i.attrs[..], "repr") {
+                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+                        if item.check_name("align") {
+                            gate_feature_post!(&self, repr_align_enum, attr.span,
+                                               "`#[repr(align(x))]` on enums is experimental");
+                        }
+                    }
+                }
+            }
+
             ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
                 if polarity == ast::ImplPolarity::Negative {
                     gate_feature_post!(&self, optin_builtin_traits,
diff --git a/src/test/run-pass/structs-enums/align-enum.rs b/src/test/run-pass/structs-enums/align-enum.rs
new file mode 100644 (file)
index 0000000..265bae8
--- /dev/null
@@ -0,0 +1,17 @@
+// run-pass
+#![allow(dead_code)]
+#![feature(repr_align_enum)]
+
+use std::mem;
+
+// Raising alignment
+#[repr(align(8))]
+enum Align8 {
+    Foo { foo: u32 },
+    Bar { bar: u32 },
+}
+
+fn main() {
+    assert_eq!(mem::align_of::<Align8>(), 8);
+    assert_eq!(mem::size_of::<Align8>(), 8);
+}
index 498bf4d284a7378e9800ff5ddcca5bd4d7f0b63c..1df2947cbe2ddd565ec4fd9c814fd241b65e1314 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(repr_simd)]
+#![feature(repr_align_enum)]
 
 #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
 fn f() {}
@@ -18,7 +19,7 @@ fn f() {}
 #[repr(C)]
 enum EExtern { A, B }
 
-#[repr(align(8))] //~ ERROR: attribute should be applied to struct
+#[repr(align(8))]
 enum EAlign { A, B }
 
 #[repr(packed)] //~ ERROR: attribute should be applied to struct
index 990984bbb2b3d03686193f11a29c93606cd9929b..abb8685e4cef0791a03abd1847eb552e8427dbe4 100644 (file)
@@ -1,5 +1,5 @@
 error[E0517]: attribute should be applied to struct, enum or union
-  --> $DIR/attr-usage-repr.rs:3:8
+  --> $DIR/attr-usage-repr.rs:4:8
    |
 LL | #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
    |        ^
@@ -7,7 +7,7 @@ LL | fn f() {}
    | --------- not a struct, enum or union
 
 error[E0517]: attribute should be applied to enum
-  --> $DIR/attr-usage-repr.rs:15:8
+  --> $DIR/attr-usage-repr.rs:16:8
    |
 LL | #[repr(i8)] //~ ERROR: attribute should be applied to enum
    |        ^^
@@ -15,15 +15,7 @@ LL | struct SInt(f64, f64);
    | ---------------------- not an enum
 
 error[E0517]: attribute should be applied to struct or union
-  --> $DIR/attr-usage-repr.rs:21:8
-   |
-LL | #[repr(align(8))] //~ ERROR: attribute should be applied to struct
-   |        ^^^^^^^^
-LL | enum EAlign { A, B }
-   | -------------------- not a struct or union
-
-error[E0517]: attribute should be applied to struct or union
-  --> $DIR/attr-usage-repr.rs:24:8
+  --> $DIR/attr-usage-repr.rs:25:8
    |
 LL | #[repr(packed)] //~ ERROR: attribute should be applied to struct
    |        ^^^^^^
@@ -31,13 +23,13 @@ LL | enum EPacked { A, B }
    | --------------------- not a struct or union
 
 error[E0517]: attribute should be applied to struct
-  --> $DIR/attr-usage-repr.rs:27:8
+  --> $DIR/attr-usage-repr.rs:28:8
    |
 LL | #[repr(simd)] //~ ERROR: attribute should be applied to struct
    |        ^^^^
 LL | enum ESimd { A, B }
    | ------------------- not a struct
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0517`.
diff --git a/src/test/ui/feature-gates/feature-gate-repr_align_enum.rs b/src/test/ui/feature-gates/feature-gate-repr_align_enum.rs
new file mode 100644 (file)
index 0000000..f8e68a9
--- /dev/null
@@ -0,0 +1,10 @@
+#[repr(align(16))]
+struct Foo(u64);
+
+#[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996)
+enum Bar {
+    Foo { foo: Foo },
+    Baz,
+}
+
+fn main() { }
diff --git a/src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr b/src/test/ui/feature-gates/feature-gate-repr_align_enum.stderr
new file mode 100644 (file)
index 0000000..6def25f
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0658]: `#[repr(align(x))]` on enums is experimental (see issue #57996)
+  --> $DIR/feature-gate-repr_align_enum.rs:4:1
+   |
+LL | #[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996)
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(repr_align_enum)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.