Skip to content

Commit c6f6101

Browse files
committed
Allow #[repr(align(x))] on enums (#57996)
1 parent 7425663 commit c6f6101

File tree

8 files changed

+87
-24
lines changed

8 files changed

+87
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# `repr_align_enum`
2+
3+
The tracking issue for this feature is: [#57996]
4+
5+
[#57996]: https://github.com/rust-lang/rust/issues/57996
6+
7+
------------------------
8+
9+
The `repr_align_enum` feature allows using the `#[repr(align(x))]` attribute
10+
on enums, similarly to structs.
11+
12+
# Examples
13+
14+
```rust
15+
#![feature(repr_align_enum)]
16+
17+
#[repr(align(8))]
18+
enum Aligned {
19+
Foo,
20+
Bar { value: u32 },
21+
}
22+
23+
fn main() {
24+
assert_eq!(std::mem::align_of::<Aligned>(), 8);
25+
}
26+
```

src/librustc/hir/check_attr.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
187187
};
188188

189189
let (article, allowed_targets) = match &*name.as_str() {
190-
"C" => {
191-
is_c = true;
190+
"C" | "align" => {
191+
is_c |= name == "C";
192192
if target != Target::Struct &&
193193
target != Target::Union &&
194194
target != Target::Enum {
@@ -213,14 +213,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
213213
continue
214214
}
215215
}
216-
"align" => {
217-
if target != Target::Struct &&
218-
target != Target::Union {
219-
("a", "struct or union")
220-
} else {
221-
continue
222-
}
223-
}
224216
"transparent" => {
225217
is_transparent = true;
226218
if target != Target::Struct {

src/libsyntax/feature_gate.rs

+14
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ declare_features! (
461461

462462
// #[optimize(X)]
463463
(active, optimize_attribute, "1.34.0", Some(54882), None),
464+
465+
// #[repr(align(X))] on enums
466+
(active, repr_align_enum, "1.34.0", Some(57996), None),
464467
);
465468

466469
declare_features! (
@@ -1697,6 +1700,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
16971700
}
16981701
}
16991702

1703+
ast::ItemKind::Enum(..) => {
1704+
for attr in attr::filter_by_name(&i.attrs[..], "repr") {
1705+
for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
1706+
if item.check_name("align") {
1707+
gate_feature_post!(&self, repr_align_enum, attr.span,
1708+
"`#[repr(align(x))]` on enums is experimental");
1709+
}
1710+
}
1711+
}
1712+
}
1713+
17001714
ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
17011715
if polarity == ast::ImplPolarity::Negative {
17021716
gate_feature_post!(&self, optin_builtin_traits,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
#![allow(dead_code)]
3+
#![feature(repr_align_enum)]
4+
5+
use std::mem;
6+
7+
// Raising alignment
8+
#[repr(align(8))]
9+
enum Align8 {
10+
Foo { foo: u32 },
11+
Bar { bar: u32 },
12+
}
13+
14+
fn main() {
15+
assert_eq!(mem::align_of::<Align8>(), 8);
16+
assert_eq!(mem::size_of::<Align8>(), 8);
17+
}

src/test/ui/attr-usage-repr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(repr_simd)]
2+
#![feature(repr_align_enum)]
23

34
#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
45
fn f() {}
@@ -18,7 +19,7 @@ struct SInt(f64, f64);
1819
#[repr(C)]
1920
enum EExtern { A, B }
2021

21-
#[repr(align(8))] //~ ERROR: attribute should be applied to struct
22+
#[repr(align(8))]
2223
enum EAlign { A, B }
2324

2425
#[repr(packed)] //~ ERROR: attribute should be applied to struct

src/test/ui/attr-usage-repr.stderr

+5-13
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,35 @@
11
error[E0517]: attribute should be applied to struct, enum or union
2-
--> $DIR/attr-usage-repr.rs:3:8
2+
--> $DIR/attr-usage-repr.rs:4:8
33
|
44
LL | #[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
55
| ^
66
LL | fn f() {}
77
| --------- not a struct, enum or union
88

99
error[E0517]: attribute should be applied to enum
10-
--> $DIR/attr-usage-repr.rs:15:8
10+
--> $DIR/attr-usage-repr.rs:16:8
1111
|
1212
LL | #[repr(i8)] //~ ERROR: attribute should be applied to enum
1313
| ^^
1414
LL | struct SInt(f64, f64);
1515
| ---------------------- not an enum
1616

1717
error[E0517]: attribute should be applied to struct or union
18-
--> $DIR/attr-usage-repr.rs:21:8
19-
|
20-
LL | #[repr(align(8))] //~ ERROR: attribute should be applied to struct
21-
| ^^^^^^^^
22-
LL | enum EAlign { A, B }
23-
| -------------------- not a struct or union
24-
25-
error[E0517]: attribute should be applied to struct or union
26-
--> $DIR/attr-usage-repr.rs:24:8
18+
--> $DIR/attr-usage-repr.rs:25:8
2719
|
2820
LL | #[repr(packed)] //~ ERROR: attribute should be applied to struct
2921
| ^^^^^^
3022
LL | enum EPacked { A, B }
3123
| --------------------- not a struct or union
3224

3325
error[E0517]: attribute should be applied to struct
34-
--> $DIR/attr-usage-repr.rs:27:8
26+
--> $DIR/attr-usage-repr.rs:28:8
3527
|
3628
LL | #[repr(simd)] //~ ERROR: attribute should be applied to struct
3729
| ^^^^
3830
LL | enum ESimd { A, B }
3931
| ------------------- not a struct
4032

41-
error: aborting due to 5 previous errors
33+
error: aborting due to 4 previous errors
4234

4335
For more information about this error, try `rustc --explain E0517`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#[repr(align(16))]
2+
struct Foo(u64);
3+
4+
#[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996)
5+
enum Bar {
6+
Foo { foo: Foo },
7+
Baz,
8+
}
9+
10+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0658]: `#[repr(align(x))]` on enums is experimental (see issue #57996)
2+
--> $DIR/feature-gate-repr_align_enum.rs:4:1
3+
|
4+
LL | #[repr(align(8))] //~ ERROR `#[repr(align(x))]` on enums is experimental (see issue #57996)
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= help: add #![feature(repr_align_enum)] to the crate attributes to enable
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)