mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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:
@@ -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>),
|
||||
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
@@ -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() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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,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() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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()]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user