diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/attributes.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/errors.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/llvm_util.rs | 10 |
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 |
