Skip to content

Commit 0516456

Browse files
committed
Port #[instruction_set] to attribute parser
1 parent ed0006a commit 0516456

File tree

19 files changed

+202
-85
lines changed

19 files changed

+202
-85
lines changed

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ attr_parsing_unstable_cfg_target_compact =
229229
attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable
230230
.help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`
231231
232+
attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]`
233+
232234
attr_parsing_unsupported_literal_suggestion =
233235
consider removing the prefix
234236
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use rustc_hir::attrs::InstructionSetAttr;
2+
3+
use super::prelude::*;
4+
use crate::session_diagnostics;
5+
6+
pub(crate) struct InstructionSetParser;
7+
8+
impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
9+
const PATH: &[Symbol] = &[sym::instruction_set];
10+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
11+
Allow(Target::Fn),
12+
Allow(Target::Closure),
13+
Allow(Target::Method(MethodKind::Inherent)),
14+
Allow(Target::Method(MethodKind::TraitImpl)),
15+
Allow(Target::Method(MethodKind::Trait { body: true })),
16+
]);
17+
const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute");
18+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
19+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
20+
21+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
22+
const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
23+
const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32];
24+
let Some(maybe_meta_item) = args.list().and_then(MetaItemListParser::single) else {
25+
cx.expected_specific_argument(cx.attr_span, POSSIBLE_SYMBOLS);
26+
return None;
27+
};
28+
29+
let Some(meta_item) = maybe_meta_item.meta_item() else {
30+
cx.expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS);
31+
return None;
32+
};
33+
34+
let mut segments = meta_item.path().segments();
35+
36+
let Some(architecture) = segments.next() else {
37+
cx.expected_specific_argument(meta_item.span(), POSSIBLE_SYMBOLS);
38+
return None;
39+
};
40+
41+
let Some(instruction_set) = segments.next() else {
42+
cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
43+
return None;
44+
};
45+
46+
let instruction_set = match architecture.name {
47+
sym::arm => {
48+
if !cx.sess.target.has_thumb_interworking {
49+
cx.dcx().emit_err(session_diagnostics::UnsupportedInstructionSet {
50+
span: cx.attr_span,
51+
instruction_set: sym::arm,
52+
current_target: &cx.sess.opts.target_triple,
53+
});
54+
return None;
55+
}
56+
match instruction_set.name {
57+
sym::a32 => InstructionSetAttr::ArmA32,
58+
sym::t32 => InstructionSetAttr::ArmT32,
59+
_ => {
60+
cx.expected_specific_argument(instruction_set.span, POSSIBLE_ARM_SYMBOLS);
61+
return None;
62+
}
63+
}
64+
}
65+
_ => {
66+
cx.expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
67+
return None;
68+
}
69+
};
70+
71+
Some(AttributeKind::InstructionSet(instruction_set))
72+
}
73+
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub(crate) mod deprecation;
4141
pub(crate) mod doc;
4242
pub(crate) mod dummy;
4343
pub(crate) mod inline;
44+
pub(crate) mod instruction_set;
4445
pub(crate) mod link_attrs;
4546
pub(crate) mod lint_helpers;
4647
pub(crate) mod loop_match;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::attributes::deprecation::DeprecationParser;
3636
use crate::attributes::doc::DocParser;
3737
use crate::attributes::dummy::DummyParser;
3838
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
39+
use crate::attributes::instruction_set::InstructionSetParser;
3940
use crate::attributes::link_attrs::{
4041
ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
4142
LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser,
@@ -194,6 +195,7 @@ attribute_parsers!(
194195
Single<ExportNameParser>,
195196
Single<IgnoreParser>,
196197
Single<InlineParser>,
198+
Single<InstructionSetParser>,
197199
Single<LinkNameParser>,
198200
Single<LinkOrdinalParser>,
199201
Single<LinkSectionParser>,

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_feature::AttributeTemplate;
99
use rustc_hir::AttrPath;
1010
use rustc_macros::{Diagnostic, Subdiagnostic};
1111
use rustc_span::{Span, Symbol};
12+
use rustc_target::spec::TargetTuple;
1213

1314
use crate::fluent_generated as fluent;
1415

@@ -926,3 +927,12 @@ pub(crate) struct DocAliasMalformed {
926927
#[primary_span]
927928
pub span: Span,
928929
}
930+
931+
#[derive(Diagnostic)]
932+
#[diag(attr_parsing_unsupported_instruction_set)]
933+
pub(crate) struct UnsupportedInstructionSet<'a> {
934+
#[primary_span]
935+
pub span: Span,
936+
pub instruction_set: Symbol,
937+
pub current_target: &'a TargetTuple,
938+
}

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to
88
99
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
1010
11-
codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument
12-
1311
codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty
1412
1513
codegen_ssa_cgu_not_recorded =
@@ -90,8 +88,6 @@ codegen_ssa_incorrect_cgu_reuse_type =
9088
9189
codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
9290
93-
codegen_ssa_invalid_instruction_set = invalid instruction set specified
94-
9591
codegen_ssa_invalid_literal_value = invalid literal value
9692
.label = value must be an integer between `0` and `255`
9793
@@ -215,8 +211,6 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but
215211
216212
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
217213
218-
codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set
219-
220214
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
221215
.help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point
222216
@@ -383,8 +377,6 @@ codegen_ssa_unstable_ctarget_feature =
383377
unstable feature specified for `-Ctarget-feature`: `{$feature}`
384378
.note = this feature is not stably supported; its behavior can change in the future
385379
386-
codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`
387-
388380
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
389381
390382
codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::str::FromStr;
33
use rustc_abi::{Align, ExternAbi};
44
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
55
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
6-
use rustc_hir::attrs::{
7-
AttributeKind, InlineAttr, InstructionSetAttr, Linkage, RtsanSetting, UsedBy,
8-
};
6+
use rustc_hir::attrs::{AttributeKind, InlineAttr, Linkage, RtsanSetting, UsedBy};
97
use rustc_hir::def::DefKind;
108
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
119
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
@@ -47,37 +45,6 @@ fn try_fn_sig<'tcx>(
4745
}
4846
}
4947

50-
// FIXME(jdonszelmann): remove when instruction_set becomes a parsed attr
51-
fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<InstructionSetAttr> {
52-
let list = attr.meta_item_list()?;
53-
54-
match &list[..] {
55-
[MetaItemInner::MetaItem(set)] => {
56-
let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
57-
match segments.as_slice() {
58-
[sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => {
59-
tcx.dcx().emit_err(errors::UnsupportedInstructionSet { span: attr.span() });
60-
None
61-
}
62-
[sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32),
63-
[sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32),
64-
_ => {
65-
tcx.dcx().emit_err(errors::InvalidInstructionSet { span: attr.span() });
66-
None
67-
}
68-
}
69-
}
70-
[] => {
71-
tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() });
72-
None
73-
}
74-
_ => {
75-
tcx.dcx().emit_err(errors::MultipleInstructionSet { span: attr.span() });
76-
None
77-
}
78-
}
79-
}
80-
8148
// FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr
8249
fn parse_patchable_function_entry(
8350
tcx: TyCtxt<'_>,
@@ -350,6 +317,9 @@ fn process_builtin_attrs(
350317
codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM;
351318
}
352319
}
320+
AttributeKind::InstructionSet(instruction_set) => {
321+
codegen_fn_attrs.instruction_set = Some(*instruction_set)
322+
}
353323
_ => {}
354324
}
355325
}
@@ -367,9 +337,6 @@ fn process_builtin_attrs(
367337
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
368338
}
369339
sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
370-
sym::instruction_set => {
371-
codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr)
372-
}
373340
sym::patchable_function_entry => {
374341
codegen_fn_attrs.patchable_function_entry =
375342
parse_patchable_function_entry(tcx, attr);

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -136,34 +136,6 @@ pub(crate) struct RequiresRustAbi {
136136
pub span: Span,
137137
}
138138

139-
#[derive(Diagnostic)]
140-
#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)]
141-
pub(crate) struct UnsupportedInstructionSet {
142-
#[primary_span]
143-
pub span: Span,
144-
}
145-
146-
#[derive(Diagnostic)]
147-
#[diag(codegen_ssa_invalid_instruction_set, code = E0779)]
148-
pub(crate) struct InvalidInstructionSet {
149-
#[primary_span]
150-
pub span: Span,
151-
}
152-
153-
#[derive(Diagnostic)]
154-
#[diag(codegen_ssa_bare_instruction_set, code = E0778)]
155-
pub(crate) struct BareInstructionSet {
156-
#[primary_span]
157-
pub span: Span,
158-
}
159-
160-
#[derive(Diagnostic)]
161-
#[diag(codegen_ssa_multiple_instruction_set, code = E0779)]
162-
pub(crate) struct MultipleInstructionSet {
163-
#[primary_span]
164-
pub span: Span,
165-
}
166-
167139
#[derive(Diagnostic)]
168140
#[diag(codegen_ssa_expected_name_value_pair)]
169141
pub(crate) struct ExpectedNameValuePair {

compiler/rustc_error_codes/src/error_codes/E0778.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
#### Note: this error code is no longer emitted by the compiler
12
The `instruction_set` attribute was malformed.
23

34
Erroneous code example:
45

5-
```compile_fail,E0778
6+
```compile_fail
67
#![feature(isa_attribute)]
78
89
#[instruction_set()] // error: expected one argument

compiler/rustc_error_codes/src/error_codes/E0779.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
#### Note: this error code is no longer emitted by the compiler
12
An unknown argument was given to the `instruction_set` attribute.
23

34
Erroneous code example:
45

5-
```compile_fail,E0779
6+
```compile_fail
67
#![feature(isa_attribute)]
78
89
#[instruction_set(intel::x64)] // error: invalid argument

0 commit comments

Comments
 (0)