about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs10
3 files changed, 39 insertions, 14 deletions
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 02eef104077..ce54c281384 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -12,7 +12,7 @@ use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtec
 use smallvec::SmallVec;
 
 use crate::attributes;
-use crate::errors::SanitizerMemtagRequiresMte;
+use crate::errors::{MissingFeatures, SanitizerMemtagRequiresMte, TargetFeatureDisableOrEnable};
 use crate::llvm::AttributePlace::Function;
 use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects};
 use crate::llvm_util;
@@ -394,13 +394,11 @@ pub fn from_fn_attrs<'ll, 'tcx>(
             .get_attrs(instance.def_id(), sym::target_feature)
             .next()
             .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
-        let msg = format!(
-            "the target features {} must all be either enabled or disabled together",
-            f.join(", ")
-        );
-        let mut err = cx.tcx.sess.struct_span_err(span, &msg);
-        err.help("add the missing features in a `target_feature` attribute");
-        err.emit();
+        cx.tcx
+            .sess
+            .create_err(TargetFeatureDisableOrEnable { features: f, span: Some(span) })
+            .subdiagnostic(MissingFeatures)
+            .emit();
         return;
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 1fe88cc2482..cd53ac4532a 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -2,7 +2,8 @@ use std::borrow::Cow;
 
 use rustc_errors::fluent;
 use rustc_errors::DiagnosticBuilder;
-use rustc_macros::SessionDiagnostic;
+use rustc_errors::ErrorGuaranteed;
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
 use rustc_session::SessionDiagnostic;
 use rustc_span::Span;
 
@@ -117,3 +118,29 @@ pub(crate) struct DlltoolFailImportLibrary<'a> {
 pub(crate) struct UnknownArchiveKind<'a> {
     pub kind: &'a str,
 }
+
+pub(crate) struct TargetFeatureDisableOrEnable<'a> {
+    pub features: &'a [&'a str],
+    pub span: Option<Span>,
+}
+
+#[derive(SessionSubdiagnostic)]
+#[help(codegen_llvm::missing_features)]
+pub(crate) struct MissingFeatures;
+
+impl SessionDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> {
+    fn into_diagnostic(
+        self,
+        sess: &'_ rustc_session::parse::ParseSess,
+    ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+        let mut diag = if let Some(span) = self.span {
+            let mut diag = sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable);
+            diag.set_span(span);
+            diag
+        } else {
+            sess.struct_err(fluent::codegen_llvm::target_feature_disable_or_enable)
+        };
+        diag.set_arg("features", self.features.join(", "));
+        diag
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 8f67913f91f..8c2db38d84d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -1,5 +1,5 @@
 use crate::back::write::create_informational_target_machine;
-use crate::errors::UnknownCTargetFeature;
+use crate::errors::{TargetFeatureDisableOrEnable, UnknownCTargetFeature};
 use crate::llvm;
 use libc::c_int;
 use rustc_codegen_ssa::target_features::{
@@ -480,10 +480,10 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
     features.extend(feats);
 
     if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
-        sess.err(&format!(
-            "target features {} must all be enabled or disabled together",
-            f.join(", ")
-        ));
+        sess.emit_err(TargetFeatureDisableOrEnable {
+            features: f,
+            span: None
+        });
     }
 
     features