From 7f7b3488c0258e1059426611267b5bd4ec068ac0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Nov 2025 15:51:24 +0000 Subject: [PATCH 1/3] Introduce InlineAsmError type --- compiler/rustc_codegen_llvm/src/back/write.rs | 16 +++++++--- compiler/rustc_codegen_ssa/src/back/write.rs | 31 ++++++++++--------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index fde7dd6ef7a85..95539059653bd 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -9,8 +9,8 @@ use libc::{c_char, c_int, c_void, size_t}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ - BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig, - TargetMachineFactoryFn, + BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, + TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::wants_wasm_eh; use rustc_codegen_ssa::traits::*; @@ -434,7 +434,7 @@ fn report_inline_asm( level: llvm::DiagnosticLevel, cookie: u64, source: Option<(String, Vec)>, -) { +) -> InlineAsmError { // In LTO build we may get srcloc values from other crates which are invalid // since they use a different source map. To be safe we just suppress these // in LTO builds. @@ -454,7 +454,7 @@ fn report_inline_asm( llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note, }; let msg = msg.trim_prefix("error: ").to_string(); - cgcx.diag_emitter.inline_asm_error(span, msg, level, source); + InlineAsmError { span, msg, level, source } } unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) { @@ -466,7 +466,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } { llvm::diagnostic::InlineAsm(inline) => { - report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source); + cgcx.diag_emitter.inline_asm_error(report_inline_asm( + cgcx, + inline.message, + inline.level, + inline.cookie, + inline.source, + )); } llvm::diagnostic::Optimization(opt) => { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index fc1edec8de843..3073b1641ac7c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1897,10 +1897,17 @@ fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( enum SharedEmitterMessage { Diagnostic(Diagnostic), - InlineAsmError(SpanData, String, Level, Option<(String, Vec)>), + InlineAsmError(InlineAsmError), Fatal(String), } +pub struct InlineAsmError { + pub span: SpanData, + pub msg: String, + pub level: Level, + pub source: Option<(String, Vec)>, +} + #[derive(Clone)] pub struct SharedEmitter { sender: Sender, @@ -1917,14 +1924,8 @@ impl SharedEmitter { (SharedEmitter { sender }, SharedEmitterMain { receiver }) } - pub fn inline_asm_error( - &self, - span: SpanData, - msg: String, - level: Level, - source: Option<(String, Vec)>, - ) { - drop(self.sender.send(SharedEmitterMessage::InlineAsmError(span, msg, level, source))); + pub fn inline_asm_error(&self, err: InlineAsmError) { + drop(self.sender.send(SharedEmitterMessage::InlineAsmError(err))); } fn fatal(&self, msg: &str) { @@ -2007,15 +2008,15 @@ impl SharedEmitterMain { dcx.emit_diagnostic(d); sess.dcx().abort_if_errors(); } - Ok(SharedEmitterMessage::InlineAsmError(span, msg, level, source)) => { - assert_matches!(level, Level::Error | Level::Warning | Level::Note); - let mut err = Diag::<()>::new(sess.dcx(), level, msg); - if !span.is_dummy() { - err.span(span.span()); + Ok(SharedEmitterMessage::InlineAsmError(inner)) => { + assert_matches!(inner.level, Level::Error | Level::Warning | Level::Note); + let mut err = Diag::<()>::new(sess.dcx(), inner.level, inner.msg); + if !inner.span.is_dummy() { + err.span(inner.span.span()); } // Point to the generated assembly if it is available. - if let Some((buffer, spans)) = source { + if let Some((buffer, spans)) = inner.source { let source = sess .source_map() .new_source_file(FileName::inline_asm_source_code(&buffer), buffer); From bba5f7f72b6d1aacd12442d538419fac480b6393 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 13:46:19 +0000 Subject: [PATCH 2/3] Remove unused pop_span_label method --- compiler/rustc_error_messages/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 64dcf3c1f72d8..085403c8ef36b 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -455,10 +455,6 @@ impl MultiSpan { replacements_occurred } - pub fn pop_span_label(&mut self) -> Option<(Span, DiagMessage)> { - self.span_labels.pop() - } - /// Returns the strings to highlight. We always ensure that there /// is an entry for each of the primary spans -- for each primary /// span `P`, if there is at least one label with span `P`, we return From 2a280130db7b6fa5a52ee42f68e130d101e73607 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Nov 2025 13:46:51 +0000 Subject: [PATCH 3/3] Allow passing primary spans to SharedEmitter --- compiler/rustc_codegen_ssa/src/back/write.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3073b1641ac7c..3e36bd8552b18 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1208,6 +1208,7 @@ pub struct CguMessage; // - `is_lint`: lints aren't relevant during codegen. // - `emitted_at`: not used for codegen diagnostics. struct Diagnostic { + span: Vec, level: Level, messages: Vec<(DiagMessage, Style)>, code: Option, @@ -1218,7 +1219,7 @@ struct Diagnostic { // A cut-down version of `rustc_errors::Subdiag` that impls `Send`. It's // missing the following fields from `rustc_errors::Subdiag`. // - `span`: it doesn't impl `Send`. -pub(crate) struct Subdiagnostic { +struct Subdiagnostic { level: Level, messages: Vec<(DiagMessage, Style)>, } @@ -1941,7 +1942,7 @@ impl Emitter for SharedEmitter { ) { // Check that we aren't missing anything interesting when converting to // the cut-down local `DiagInner`. - assert_eq!(diag.span, MultiSpan::new()); + assert!(!diag.span.has_span_labels()); assert_eq!(diag.suggestions, Suggestions::Enabled(vec![])); assert_eq!(diag.sort_span, rustc_span::DUMMY_SP); assert_eq!(diag.is_lint, None); @@ -1950,6 +1951,7 @@ impl Emitter for SharedEmitter { let args = mem::replace(&mut diag.args, DiagArgMap::default()); drop( self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { + span: diag.span.primary_spans().iter().map(|span| span.data()).collect::>(), level: diag.level(), messages: diag.messages, code: diag.code, @@ -1994,6 +1996,9 @@ impl SharedEmitterMain { let dcx = sess.dcx(); let mut d = rustc_errors::DiagInner::new_with_messages(diag.level, diag.messages); + d.span = MultiSpan::from_spans( + diag.span.into_iter().map(|span| span.span()).collect(), + ); d.code = diag.code; // may be `None`, that's ok d.children = diag .children