Skip to content

Commit 383a353

Browse files
committed
move -Ctarget-feature handling into shared code
1 parent aab5145 commit 383a353

File tree

11 files changed

+288
-395
lines changed

11 files changed

+288
-395
lines changed

compiler/rustc_codegen_gcc/src/errors.rs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,6 @@
1-
use rustc_macros::{Diagnostic, Subdiagnostic};
1+
use rustc_macros::Diagnostic;
22
use rustc_span::Span;
33

4-
#[derive(Diagnostic)]
5-
#[diag(codegen_gcc_unknown_ctarget_feature_prefix)]
6-
#[note]
7-
pub(crate) struct UnknownCTargetFeaturePrefix<'a> {
8-
pub feature: &'a str,
9-
}
10-
11-
#[derive(Diagnostic)]
12-
#[diag(codegen_gcc_unknown_ctarget_feature)]
13-
#[note]
14-
pub(crate) struct UnknownCTargetFeature<'a> {
15-
pub feature: &'a str,
16-
#[subdiagnostic]
17-
pub rust_feature: PossibleFeature<'a>,
18-
}
19-
20-
#[derive(Diagnostic)]
21-
#[diag(codegen_gcc_unstable_ctarget_feature)]
22-
#[note]
23-
pub(crate) struct UnstableCTargetFeature<'a> {
24-
pub feature: &'a str,
25-
}
26-
27-
#[derive(Diagnostic)]
28-
#[diag(codegen_gcc_forbidden_ctarget_feature)]
29-
pub(crate) struct ForbiddenCTargetFeature<'a> {
30-
pub feature: &'a str,
31-
pub enabled: &'a str,
32-
pub reason: &'a str,
33-
}
34-
35-
#[derive(Subdiagnostic)]
36-
pub(crate) enum PossibleFeature<'a> {
37-
#[help(codegen_gcc_possible_feature)]
38-
Some { rust_feature: &'a str },
39-
#[help(codegen_gcc_consider_filing_feature_request)]
40-
None,
41-
}
42-
434
#[derive(Diagnostic)]
445
#[diag(codegen_gcc_unwinding_inline_asm)]
456
pub(crate) struct UnwindingInlineAsm {

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 18 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
#[cfg(feature = "master")]
22
use gccjit::Context;
3-
use rustc_codegen_ssa::codegen_attrs::check_tied_features;
4-
use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable;
5-
use rustc_data_structures::fx::FxHashMap;
6-
use rustc_data_structures::unord::UnordSet;
3+
use rustc_middle::target_features;
74
use rustc_session::Session;
8-
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
95
use smallvec::{SmallVec, smallvec};
106

11-
use crate::errors::{
12-
ForbiddenCTargetFeature, PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix,
13-
UnstableCTargetFeature,
14-
};
15-
167
/// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`,
178
/// `--target` and similar).
189
pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<String> {
@@ -40,109 +31,27 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec<Stri
4031
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));
4132

4233
// -Ctarget-features
43-
let known_features = sess.target.rust_target_features();
44-
let mut featsmap = FxHashMap::default();
45-
46-
// Compute implied features
47-
let mut all_rust_features = vec![];
48-
for feature in sess.opts.cg.target_feature.split(',') {
49-
if let Some(feature) = feature.strip_prefix('+') {
50-
all_rust_features.extend(
51-
UnordSet::from(sess.target.implied_target_features(feature))
52-
.to_sorted_stable_ord()
53-
.iter()
54-
.map(|&&s| (true, s)),
55-
)
56-
} else if let Some(feature) = feature.strip_prefix('-') {
57-
// FIXME: Why do we not remove implied features on "-" here?
58-
// We do the equivalent above in `target_config`.
59-
// See <https://github.com/rust-lang/rust/issues/134792>.
60-
all_rust_features.push((false, feature));
61-
} else if !feature.is_empty() && diagnostics {
62-
sess.dcx().emit_warn(UnknownCTargetFeaturePrefix { feature });
63-
}
64-
}
65-
// Remove features that are meant for rustc, not codegen.
66-
all_rust_features.retain(|&(_, feature)| {
67-
// Retain if it is not a rustc feature
68-
!RUSTC_SPECIFIC_FEATURES.contains(&feature)
69-
});
70-
71-
// Check feature validity.
72-
if diagnostics {
73-
for &(enable, feature) in &all_rust_features {
74-
let feature_state = known_features.iter().find(|&&(v, _, _)| v == feature);
75-
match feature_state {
76-
None => {
77-
let rust_feature = known_features.iter().find_map(|&(rust_feature, _, _)| {
78-
let gcc_features = to_gcc_features(sess, rust_feature);
79-
if gcc_features.contains(&feature) && !gcc_features.contains(&rust_feature)
80-
{
81-
Some(rust_feature)
82-
} else {
83-
None
84-
}
85-
});
86-
let unknown_feature = if let Some(rust_feature) = rust_feature {
87-
UnknownCTargetFeature {
88-
feature,
89-
rust_feature: PossibleFeature::Some { rust_feature },
90-
}
91-
} else {
92-
UnknownCTargetFeature { feature, rust_feature: PossibleFeature::None }
93-
};
94-
sess.dcx().emit_warn(unknown_feature);
95-
}
96-
Some(&(_, stability, _)) => {
97-
if let Err(reason) = stability.toggle_allowed() {
98-
sess.dcx().emit_warn(ForbiddenCTargetFeature {
99-
feature,
100-
enabled: if enable { "enabled" } else { "disabled" },
101-
reason,
102-
});
103-
} else if stability.requires_nightly().is_some() {
104-
// An unstable feature. Warn about using it. (It makes little sense
105-
// to hard-error here since we just warn about fully unknown
106-
// features above).
107-
sess.dcx().emit_warn(UnstableCTargetFeature { feature });
108-
}
109-
}
110-
}
111-
112-
// FIXME(nagisa): figure out how to not allocate a full hashset here.
113-
featsmap.insert(feature, enable);
114-
}
115-
}
116-
117-
// Translate this into GCC features.
118-
let feats =
119-
all_rust_features.iter().flat_map(|&(enable, feature)| {
120-
let enable_disable = if enable { '+' } else { '-' };
34+
target_features::flag_to_backend_features(
35+
sess,
36+
diagnostics,
37+
|feature| to_gcc_features(sess, feature),
38+
|feature, enable| {
12139
// We run through `to_gcc_features` when
12240
// passing requests down to GCC. This means that all in-language
12341
// features also work on the command line instead of having two
12442
// different names when the GCC name and the Rust name differ.
125-
to_gcc_features(sess, feature)
126-
.iter()
127-
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
128-
.map(|feature| {
129-
if enable_disable == '-' {
130-
format!("-{}", feature)
131-
} else {
132-
feature.to_string()
133-
}
134-
})
135-
.collect::<Vec<_>>()
136-
});
137-
features.extend(feats);
138-
139-
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
140-
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
141-
features: f,
142-
span: None,
143-
missing_features: None,
144-
});
145-
}
43+
features.extend(
44+
to_gcc_features(sess, feature)
45+
.iter()
46+
.flat_map(|feat| to_gcc_features(sess, feat).into_iter())
47+
.map(
48+
|feature| {
49+
if !enable { format!("-{}", feature) } else { feature.to_string() }
50+
},
51+
),
52+
);
53+
},
54+
);
14655

14756
features
14857
}

compiler/rustc_codegen_llvm/messages.ftl

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ codegen_llvm_dynamic_linking_with_lto =
1010
1111
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
1212
13-
codegen_llvm_forbidden_ctarget_feature =
14-
target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}
15-
.note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
16-
codegen_llvm_forbidden_ctarget_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
17-
1813
codegen_llvm_from_llvm_diag = {$message}
1914
2015
codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}
@@ -70,22 +65,8 @@ codegen_llvm_symbol_already_defined =
7065
codegen_llvm_target_machine = could not create LLVM TargetMachine for triple: {$triple}
7166
codegen_llvm_target_machine_with_llvm_err = could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err}
7267
73-
codegen_llvm_unknown_ctarget_feature =
74-
unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
75-
.note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
76-
.possible_feature = you might have meant: `{$rust_feature}`
77-
.consider_filing_feature_request = consider filing a feature request
78-
79-
codegen_llvm_unknown_ctarget_feature_prefix =
80-
unknown feature specified for `-Ctarget-feature`: `{$feature}`
81-
.note = features must begin with a `+` to enable or `-` to disable it
82-
8368
codegen_llvm_unknown_debuginfo_compression = unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo
8469
85-
codegen_llvm_unstable_ctarget_feature =
86-
unstable feature specified for `-Ctarget-feature`: `{$feature}`
87-
.note = this feature is not stably supported; its behavior can change in the future
88-
8970
codegen_llvm_write_bytecode = failed to write bytecode to {$path}: {$err}
9071
9172
codegen_llvm_write_ir = failed to write LLVM IR to {$path}

compiler/rustc_codegen_llvm/src/errors.rs

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,11 @@ use std::path::Path;
33

44
use rustc_data_structures::small_c_str::SmallCStr;
55
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
6-
use rustc_macros::{Diagnostic, Subdiagnostic};
6+
use rustc_macros::Diagnostic;
77
use rustc_span::Span;
88

99
use crate::fluent_generated as fluent;
1010

11-
#[derive(Diagnostic)]
12-
#[diag(codegen_llvm_unknown_ctarget_feature_prefix)]
13-
#[note]
14-
pub(crate) struct UnknownCTargetFeaturePrefix<'a> {
15-
pub feature: &'a str,
16-
}
17-
18-
#[derive(Diagnostic)]
19-
#[diag(codegen_llvm_unknown_ctarget_feature)]
20-
#[note]
21-
pub(crate) struct UnknownCTargetFeature<'a> {
22-
pub feature: &'a str,
23-
#[subdiagnostic]
24-
pub rust_feature: PossibleFeature<'a>,
25-
}
26-
27-
#[derive(Diagnostic)]
28-
#[diag(codegen_llvm_unstable_ctarget_feature)]
29-
#[note]
30-
pub(crate) struct UnstableCTargetFeature<'a> {
31-
pub feature: &'a str,
32-
}
33-
34-
#[derive(Diagnostic)]
35-
#[diag(codegen_llvm_forbidden_ctarget_feature)]
36-
#[note]
37-
#[note(codegen_llvm_forbidden_ctarget_feature_issue)]
38-
pub(crate) struct ForbiddenCTargetFeature<'a> {
39-
pub feature: &'a str,
40-
pub enabled: &'a str,
41-
pub reason: &'a str,
42-
}
43-
44-
#[derive(Subdiagnostic)]
45-
pub(crate) enum PossibleFeature<'a> {
46-
#[help(codegen_llvm_possible_feature)]
47-
Some { rust_feature: &'a str },
48-
#[help(codegen_llvm_consider_filing_feature_request)]
49-
None,
50-
}
51-
5211
#[derive(Diagnostic)]
5312
#[diag(codegen_llvm_symbol_already_defined)]
5413
pub(crate) struct SymbolAlreadyDefined<'a> {

0 commit comments

Comments
 (0)