add #[align] attribute

Right now it's used for functions with `fn_align`, in the future it will
get more uses (statics, struct fields, etc.)
This commit is contained in:
Folkert de Vries
2025-06-09 20:08:52 +02:00
parent 1bb335244c
commit 1fdf2b5620
30 changed files with 322 additions and 135 deletions
@@ -182,6 +182,9 @@ pub fn is_since_rustc_version(&self) -> bool {
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub enum AttributeKind {
// tidy-alphabetical-start
/// Represents `#[align(N)]`.
Align { align: Align, span: Span },
/// Represents `#[rustc_allow_const_fn_unstable]`.
AllowConstFnUnstable(ThinVec<Symbol>),
+3
View File
@@ -44,6 +44,9 @@ attr_parsing_incorrect_repr_format_packed_expect_integer =
attr_parsing_incorrect_repr_format_packed_one_or_zero_arg =
incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
attr_parsing_invalid_alignment_value =
invalid alignment value: {$error_part}
attr_parsing_invalid_issue_string =
`issue` must be a non-zero numeric string or "none"
.must_not_be_zero = `issue` must not be "0", use "none" instead
@@ -4,7 +4,7 @@
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use super::{CombineAttributeParser, ConvertFn};
use super::{AcceptMapping, AttributeParser, CombineAttributeParser, ConvertFn, FinalizeContext};
use crate::context::{AcceptContext, Stage};
use crate::parser::{ArgParser, MetaItemListParser, MetaItemParser};
use crate::session_diagnostics;
@@ -203,7 +203,7 @@ fn parse_repr_align<S: Stage>(
});
}
Align => {
cx.dcx().emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
cx.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
span: param_span,
});
}
@@ -266,3 +266,57 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
Err("not an unsuffixed integer")
}
}
/// Parse #[align(N)].
#[derive(Default)]
pub(crate) struct AlignParser(Option<(Align, Span)>);
impl AlignParser {
const PATH: &'static [Symbol] = &[sym::align];
const TEMPLATE: AttributeTemplate = template!(Word, List: "<alignment in bytes>");
fn parse<'c, S: Stage>(
&mut self,
cx: &'c mut AcceptContext<'_, '_, S>,
args: &'c ArgParser<'_>,
) {
match args {
ArgParser::NoArgs | ArgParser::NameValue(_) => {
cx.expected_list(cx.attr_span);
}
ArgParser::List(list) => {
let Some(align) = list.single() else {
cx.expected_single_argument(list.span);
return;
};
let Some(lit) = align.lit() else {
cx.emit_err(session_diagnostics::IncorrectReprFormatExpectInteger {
span: align.span(),
});
return;
};
match parse_alignment(&lit.kind) {
Ok(literal) => self.0 = Ord::max(self.0, Some((literal, cx.attr_span))),
Err(message) => {
cx.emit_err(session_diagnostics::InvalidAlignmentValue {
span: lit.span,
error_part: message,
});
}
}
}
}
}
}
impl<S: Stage> AttributeParser<S> for AlignParser {
const ATTRIBUTES: AcceptMapping<Self, S> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
let (align, span) = self.0?;
Some(AttributeKind::Align { align, span })
}
}
+2 -1
View File
@@ -19,7 +19,7 @@
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::lint_helpers::AsPtrParser;
use crate::attributes::repr::ReprParser;
use crate::attributes::repr::{AlignParser, ReprParser};
use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
@@ -90,6 +90,7 @@ mod late {
attribute_parsers!(
pub(crate) static ATTRIBUTE_PARSERS = [
// tidy-alphabetical-start
AlignParser,
BodyStabilityParser,
ConfusablesParser,
ConstStabilityParser,
@@ -450,6 +450,14 @@ pub(crate) struct EmptyConfusables {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_parsing_invalid_alignment_value, code = E0589)]
pub(crate) struct InvalidAlignmentValue {
#[primary_span]
pub span: Span,
pub error_part: &'static str,
}
#[derive(Diagnostic)]
#[diag(attr_parsing_repr_ident, code = E0565)]
pub(crate) struct ReprIdent {
@@ -3,7 +3,6 @@
use rustc_abi::ExternAbi;
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
use rustc_attr_data_structures::ReprAttr::ReprAlign;
use rustc_attr_data_structures::{
AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, find_attr,
};
@@ -110,17 +109,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
};
if let hir::Attribute::Parsed(p) = attr {
match p {
AttributeKind::Repr(reprs) => {
codegen_fn_attrs.alignment = reprs
.iter()
.filter_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None })
.max();
}
_ => {}
}
if let hir::Attribute::Parsed(AttributeKind::Align { align, .. }) = attr {
codegen_fn_attrs.alignment = Some(*align);
}
let Some(Ident { name, .. }) = attr.ident() else {
@@ -495,6 +495,7 @@ pub struct BuiltinAttribute {
),
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
@@ -47,8 +47,7 @@ pub struct CodegenFnAttrs {
/// be generated against a specific instruction set. Only usable on architectures which allow
/// switching between multiple instruction sets.
pub instruction_set: Option<InstructionSetAttr>,
/// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be
/// aligned to.
/// The `#[align(...)]` attribute. Determines the alignment of the function body.
pub alignment: Option<Align>,
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
/// the function entry.
@@ -289,6 +289,7 @@ fn emit_malformed_attribute(
| sym::rustc_force_inline
| sym::rustc_confusables
| sym::repr
| sym::align
| sym::deprecated
) {
return;
+8 -7
View File
@@ -13,6 +13,10 @@ passes_abi_ne =
passes_abi_of =
fn_abi_of({$fn_name}) = {$fn_abi}
passes_align_should_be_repr_align =
`#[align(...)]` is not supported on {$item} items
.suggestion = use `#[repr(align(...))]` instead
passes_allow_incoherent_impl =
`rustc_allow_incoherent_impl` attribute should be applied to impl items
.label = the only currently supported targets are inherent methods
@@ -29,10 +33,6 @@ passes_attr_application_struct =
attribute should be applied to a struct
.label = not a struct
passes_attr_application_struct_enum_function_method_union =
attribute should be applied to a struct, enum, function, associated function, or union
.label = not a struct, enum, function, associated function, or union
passes_attr_application_struct_enum_union =
attribute should be applied to a struct, enum, or union
.label = not a struct, enum, or union
@@ -583,13 +583,14 @@ passes_remove_fields =
*[other] fields
}
passes_repr_align_function =
`repr(align)` attributes on functions are unstable
passes_repr_align_greater_than_target_max =
alignment must not be greater than `isize::MAX` bytes
.note = `isize::MAX` is {$size} for the current target
passes_repr_align_should_be_align =
`#[repr(align(...))]` is not supported on {$item} items
.help = use `#[align(...)]` instead
passes_repr_conflicting =
conflicting representation hints
+46 -29
View File
@@ -146,6 +146,10 @@ fn check_attributes(
}
Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */
}
Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => {
self.check_align(span, target, *align, *repr_span)
}
Attribute::Parsed(
AttributeKind::BodyStability { .. }
| AttributeKind::ConstStabilityIndirect
@@ -643,6 +647,7 @@ fn check_naked(
sym::naked,
sym::instruction_set,
sym::repr,
sym::align,
sym::rustc_std_internal_symbol,
// code generation
sym::cold,
@@ -679,7 +684,9 @@ fn check_naked(
// this check can be part of the parser and be removed here
match other_attr {
Attribute::Parsed(
AttributeKind::Deprecation { .. } | AttributeKind::Repr { .. },
AttributeKind::Deprecation { .. }
| AttributeKind::Repr { .. }
| AttributeKind::Align { .. },
) => {
continue;
}
@@ -1964,6 +1971,28 @@ fn check_no_mangle(&self, hir_id: HirId, attr: &Attribute, span: Span, target: T
}
}
/// Checks if the `#[align]` attributes on `item` are valid.
fn check_align(&self, span: Span, target: Target, align: Align, repr_span: Span) {
match target {
Target::Fn | Target::Method(_) => {}
Target::Struct | Target::Union | Target::Enum => {
self.dcx().emit_err(errors::AlignShouldBeReprAlign {
span: repr_span,
item: target.name(),
align_bytes: align.bytes(),
});
}
_ => {
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
hint_span: repr_span,
span,
});
}
}
self.check_align_value(align, repr_span);
}
/// Checks if the `#[repr]` attributes on `item` are valid.
fn check_repr(
&self,
@@ -2016,23 +2045,16 @@ fn check_repr(
match target {
Target::Struct | Target::Union | Target::Enum => {}
Target::Fn | Target::Method(_) => {
if !self.tcx.features().fn_align() {
feature_err(
&self.tcx.sess,
sym::fn_align,
*repr_span,
fluent::passes_repr_align_function,
)
.emit();
}
self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
span: *repr_span,
item: target.name(),
});
}
_ => {
self.dcx().emit_err(
errors::AttrApplication::StructEnumFunctionMethodUnion {
hint_span: *repr_span,
span,
},
);
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
hint_span: *repr_span,
span,
});
}
}
@@ -2090,21 +2112,16 @@ fn check_repr(
match target {
Target::Struct | Target::Union | Target::Enum => continue,
Target::Fn | Target::Method(_) => {
feature_err(
&self.tcx.sess,
sym::fn_align,
*repr_span,
fluent::passes_repr_align_function,
)
.emit();
self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
span: *repr_span,
item: target.name(),
});
}
_ => {
self.dcx().emit_err(
errors::AttrApplication::StructEnumFunctionMethodUnion {
hint_span: *repr_span,
span,
},
);
self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
hint_span: *repr_span,
span,
});
}
}
}
+23 -7
View File
@@ -1308,13 +1308,6 @@ pub(crate) enum AttrApplication {
#[label]
span: Span,
},
#[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
StructEnumFunctionMethodUnion {
#[primary_span]
hint_span: Span,
#[label]
span: Span,
},
}
#[derive(Diagnostic)]
@@ -1816,3 +1809,26 @@ pub(crate) enum UnexportableItem<'a> {
field_name: &'a str,
},
}
#[derive(Diagnostic)]
#[diag(passes_repr_align_should_be_align)]
pub(crate) struct ReprAlignShouldBeAlign {
#[primary_span]
#[help]
pub span: Span,
pub item: &'static str,
}
#[derive(Diagnostic)]
#[diag(passes_align_should_be_repr_align)]
pub(crate) struct AlignShouldBeReprAlign {
#[primary_span]
#[suggestion(
style = "verbose",
applicability = "machine-applicable",
code = "#[repr(align({align_bytes}))]"
)]
pub span: Span,
pub item: &'static str,
pub align_bytes: u64,
}
+5 -5
View File
@@ -1,21 +1,21 @@
//@compile-flags: -Zmin-function-alignment=8
#![feature(fn_align)]
// When a function uses `repr(align(N))`, the function address should be a multiple of `N`.
// When a function uses `align(N)`, the function address should be a multiple of `N`.
#[repr(align(256))]
#[align(256)]
fn foo() {}
#[repr(align(16))]
#[align(16)]
fn bar() {}
#[repr(align(4))]
#[align(4)]
fn baz() {}
fn main() {
assert!((foo as usize).is_multiple_of(256));
assert!((bar as usize).is_multiple_of(16));
// The maximum of `repr(align(N))` and `-Zmin-function-alignment=N` is used.
// The maximum of `align(N)` and `-Zmin-function-alignment=N` is used.
assert!((baz as usize).is_multiple_of(8));
}
+1 -1
View File
@@ -37,7 +37,7 @@ extern "C" fn nop() {
#[unsafe(naked)]
#[linkage = "weak"]
// wasm functions cannot be aligned, so this has no effect
#[repr(align(32))]
#[align(32)]
extern "C" fn weak_aligned_nop() {
naked_asm!("nop")
}
+12 -10
View File
@@ -5,7 +5,7 @@
// CHECK: align 16
#[no_mangle]
#[repr(align(16))]
#[align(16)]
pub fn fn_align() {}
pub struct A;
@@ -13,12 +13,12 @@ pub fn fn_align() {}
impl A {
// CHECK: align 16
#[no_mangle]
#[repr(align(16))]
#[align(16)]
pub fn method_align(self) {}
// CHECK: align 16
#[no_mangle]
#[repr(align(16))]
#[align(16)]
pub fn associated_fn() {}
}
@@ -26,19 +26,19 @@ trait T: Sized {
fn trait_fn() {}
// CHECK: align 32
#[repr(align(32))]
#[align(32)]
fn trait_method(self) {}
}
impl T for A {
// CHECK: align 16
#[no_mangle]
#[repr(align(16))]
#[align(16)]
fn trait_fn() {}
// CHECK: align 16
#[no_mangle]
#[repr(align(16))]
#[align(16)]
fn trait_method(self) {}
}
@@ -51,18 +51,20 @@ pub fn foo() {
// CHECK-LABEL: align_specified_twice_1
// CHECK-SAME: align 64
#[no_mangle]
#[repr(align(32), align(64))]
#[align(32)]
#[align(64)]
pub fn align_specified_twice_1() {}
// CHECK-LABEL: align_specified_twice_2
// CHECK-SAME: align 128
#[no_mangle]
#[repr(align(128), align(32))]
#[align(128)]
#[align(32)]
pub fn align_specified_twice_2() {}
// CHECK-LABEL: align_specified_twice_3
// CHECK-SAME: align 256
#[no_mangle]
#[repr(align(32))]
#[repr(align(256))]
#[align(32)]
#[align(256)]
pub fn align_specified_twice_3() {}
+3 -3
View File
@@ -18,16 +18,16 @@ pub fn no_explicit_align() {}
// align16: align 16
// align1024: align 1024
#[no_mangle]
#[repr(align(8))]
#[align(8)]
pub fn lower_align() {}
// the higher value of min-function-alignment and repr(align) wins out
// the higher value of min-function-alignment and the align attribute wins out
//
// CHECK-LABEL: @higher_align
// align16: align 32
// align1024: align 1024
#[no_mangle]
#[repr(align(32))]
#[align(32)]
pub fn higher_align() {}
// cold functions follow the same rules as other functions
+1 -1
View File
@@ -8,7 +8,7 @@
// CHECK: .balign 16
// CHECK-LABEL: naked_empty:
#[repr(align(16))]
#[align(16)]
#[no_mangle]
#[unsafe(naked)]
pub extern "C" fn naked_empty() {
@@ -16,7 +16,7 @@ pub extern "C" fn naked_no_explicit_align() {
// CHECK: .balign 16
#[no_mangle]
#[repr(align(8))]
#[align(8)]
#[unsafe(naked)]
pub extern "C" fn naked_lower_align() {
core::arch::naked_asm!("ret")
@@ -24,7 +24,7 @@ pub extern "C" fn naked_lower_align() {
// CHECK: .balign 32
#[no_mangle]
#[repr(align(32))]
#[align(32)]
#[unsafe(naked)]
pub extern "C" fn naked_higher_align() {
core::arch::naked_asm!("ret")
+2 -1
View File
@@ -19,8 +19,9 @@ extern "C" fn example2() {
naked_asm!("")
}
#[repr(align(16), C)]
#[repr(C)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
#[align(16)]
#[unsafe(naked)]
extern "C" fn example3() {
//~^ NOTE not a struct, enum, or union
@@ -23,10 +23,10 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:22:19
--> $DIR/naked-with-invalid-repr-attr.rs:22:8
|
LL | #[repr(align(16), C)]
| ^
LL | #[repr(C)]
| ^
...
LL | / extern "C" fn example3() {
LL | |
@@ -35,7 +35,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/naked-with-invalid-repr-attr.rs:31:8
--> $DIR/naked-with-invalid-repr-attr.rs:32:8
|
LL | #[repr(C, packed)]
| ^
@@ -48,7 +48,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct or union
--> $DIR/naked-with-invalid-repr-attr.rs:31:11
--> $DIR/naked-with-invalid-repr-attr.rs:32:11
|
LL | #[repr(C, packed)]
| ^^^^^^
@@ -61,7 +61,7 @@ LL | | }
| |_- not a struct or union
error[E0517]: attribute should be applied to an enum
--> $DIR/naked-with-invalid-repr-attr.rs:41:8
--> $DIR/naked-with-invalid-repr-attr.rs:42:8
|
LL | #[repr(u8)]
| ^^
@@ -1,9 +1,3 @@
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/arg-error-issue-121425.rs:16:8
|
LL | #[repr(align())]
| ^^^^^^^
error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
--> $DIR/arg-error-issue-121425.rs:4:14
|
@@ -22,6 +16,12 @@ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
LL | #[repr(align("str"))]
| ^^^^^
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/arg-error-issue-121425.rs:16:8
|
LL | #[repr(align())]
| ^^^^^^^
error[E0552]: incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument
--> $DIR/arg-error-issue-121425.rs:21:15
|
+1 -1
View File
@@ -1,5 +1,5 @@
#[repr(align(16))]
//~^ ERROR attribute should be applied to a struct, enum, function, associated function, or union
//~^ ERROR attribute should be applied to a struct, enum, or union
pub type Foo = i32;
fn main() {}
+2 -2
View File
@@ -1,11 +1,11 @@
error[E0517]: attribute should be applied to a struct, enum, function, associated function, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/invalid-repr.rs:1:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
LL |
LL | pub type Foo = i32;
| ------------------- not a struct, enum, function, associated function, or union
| ------------------- not a struct, enum, or union
error: aborting due to 1 previous error
+16 -1
View File
@@ -2,6 +2,21 @@
#![crate_type = "lib"]
trait MyTrait {
#[repr(align)] //~ ERROR invalid `repr(align)` attribute: `align` needs an argument
#[align] //~ ERROR malformed `align` attribute input
fn myfun();
}
#[align = 16] //~ ERROR malformed `align` attribute input
fn f1() {}
#[align("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer
fn f2() {}
#[align(0)] //~ ERROR invalid alignment value: not a power of two
fn f3() {}
#[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on function items
fn f4() {}
#[align(16)] //~ ERROR `#[align(...)]` is not supported on struct items
struct S1;
+63 -6
View File
@@ -1,9 +1,66 @@
error[E0589]: invalid `repr(align)` attribute: `align` needs an argument
--> $DIR/malformed-fn-align.rs:5:12
error[E0539]: malformed `align` attribute input
--> $DIR/malformed-fn-align.rs:5:5
|
LL | #[repr(align)]
| ^^^^^ help: supply an argument here: `align(...)`
LL | #[align]
| ^^^^^^^^ expected this to be a list
|
help: try changing it to one of the following valid forms of the attribute
|
LL | #[align(<alignment in bytes>)]
| ++++++++++++++++++++++
error: aborting due to 1 previous error
error[E0539]: malformed `align` attribute input
--> $DIR/malformed-fn-align.rs:9:1
|
LL | #[align = 16]
| ^^^^^^^^^^^^^ expected this to be a list
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[align = 16]
LL + #[align(<alignment in bytes>)]
|
LL - #[align = 16]
LL + #[align]
|
For more information about this error, try `rustc --explain E0589`.
error[E0589]: invalid alignment value: not an unsuffixed integer
--> $DIR/malformed-fn-align.rs:12:9
|
LL | #[align("hello")]
| ^^^^^^^
error[E0589]: invalid alignment value: not a power of two
--> $DIR/malformed-fn-align.rs:15:9
|
LL | #[align(0)]
| ^
error: `#[repr(align(...))]` is not supported on function items
--> $DIR/malformed-fn-align.rs:18:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
|
help: use `#[align(...)]` instead
--> $DIR/malformed-fn-align.rs:18:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
error: `#[align(...)]` is not supported on struct items
--> $DIR/malformed-fn-align.rs:21:1
|
LL | #[align(16)]
| ^^^^^^^^^^^^
|
help: use `#[repr(align(...))]` instead
|
LL - #[align(16)]
LL + #[repr(align(16))]
|
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0539, E0589.
For more information about an error, try `rustc --explain E0539`.
@@ -1,9 +1,12 @@
#![crate_type = "lib"]
#[repr(align(16))] //~ ERROR `repr(align)` attributes on functions are unstable
#[align(16)]
//~^ ERROR the `#[align]` attribute is an experimental feature
fn requires_alignment() {}
trait MyTrait {
#[repr(align)] //~ ERROR invalid `repr(align)` attribute: `align` needs an argument
#[align]
//~^ ERROR the `#[align]` attribute is an experimental feature
//~| ERROR malformed `align` attribute input
fn myfun();
}
@@ -1,20 +1,35 @@
error[E0589]: invalid `repr(align)` attribute: `align` needs an argument
--> $DIR/feature-gate-fn_align.rs:7:12
error[E0658]: the `#[align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:3:1
|
LL | #[repr(align)]
| ^^^^^ help: supply an argument here: `align(...)`
error[E0658]: `repr(align)` attributes on functions are unstable
--> $DIR/feature-gate-fn_align.rs:3:8
|
LL | #[repr(align(16))]
| ^^^^^^^^^
LL | #[align(16)]
| ^^^^^^^^^^^^
|
= note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
= help: add `#![feature(fn_align)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors
error[E0658]: the `#[align]` attribute is an experimental feature
--> $DIR/feature-gate-fn_align.rs:8:5
|
LL | #[align]
| ^^^^^^^^
|
= note: see issue #82232 <https://github.com/rust-lang/rust/issues/82232> for more information
= help: add `#![feature(fn_align)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
Some errors have detailed explanations: E0589, E0658.
For more information about an error, try `rustc --explain E0589`.
error[E0539]: malformed `align` attribute input
--> $DIR/feature-gate-fn_align.rs:8:5
|
LL | #[align]
| ^^^^^^^^ expected this to be a list
|
help: try changing it to one of the following valid forms of the attribute
|
LL | #[align(<alignment in bytes>)]
| ++++++++++++++++++++++
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0539, E0658.
For more information about an error, try `rustc --explain E0539`.
+1 -1
View File
@@ -45,7 +45,7 @@ enum EInt {
B,
}
#[repr()] //~ ERROR attribute should be applied to a struct, enum, function, associated function, or union [E0517]
#[repr()] //~ ERROR attribute should be applied to a struct, enum, or union [E0517]
type SirThisIsAType = i32;
#[repr()]
+2 -2
View File
@@ -36,13 +36,13 @@ LL | | B,
LL | | }
| |_- not a struct
error[E0517]: attribute should be applied to a struct, enum, function, associated function, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/attr-usage-repr.rs:48:1
|
LL | #[repr()]
| ^^^^^^^^^
LL | type SirThisIsAType = i32;
| -------------------------- not a struct, enum, function, associated function, or union
| -------------------------- not a struct, enum, or union
error: aborting due to 5 previous errors
+12 -12
View File
@@ -1,15 +1,3 @@
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/malformed-repr-hints.rs:14:8
|
LL | #[repr(align(2, 4))]
| ^^^^^^^^^^^
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/malformed-repr-hints.rs:18:8
|
LL | #[repr(align())]
| ^^^^^^^
error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
--> $DIR/malformed-repr-hints.rs:6:8
|
@@ -22,6 +10,18 @@ error[E0589]: invalid `repr(align)` attribute: `align` needs an argument
LL | #[repr(align)]
| ^^^^^ help: supply an argument here: `align(...)`
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/malformed-repr-hints.rs:14:8
|
LL | #[repr(align(2, 4))]
| ^^^^^^^^^^^
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
--> $DIR/malformed-repr-hints.rs:18:8
|
LL | #[repr(align())]
| ^^^^^^^
error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list
--> $DIR/malformed-repr-hints.rs:23:8
|