From 406e1dc8ebdeb509515c0c8be7cfe015c5eced30 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 19 Oct 2022 00:08:20 +0200 Subject: Implement -Ztrack-diagnostics --- compiler/rustc_errors/src/diagnostic.rs | 29 ++++++++++++++++++++ compiler/rustc_errors/src/diagnostic_builder.rs | 5 ++++ compiler/rustc_errors/src/emitter.rs | 36 +++++++++++++++++++++---- compiler/rustc_errors/src/json.rs | 8 ++++++ compiler/rustc_errors/src/json/tests.rs | 1 + compiler/rustc_errors/src/lib.rs | 30 +++++++++++++++++++++ 6 files changed, 104 insertions(+), 5 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 518c59dba53..1ea6d82891f 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP}; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; +use std::panic::Location; /// Error type for `Diagnostic`'s `suggestions` field, indicating that /// `.disable_suggestions()` was called on the `Diagnostic`. @@ -107,6 +108,31 @@ pub struct Diagnostic { /// If diagnostic is from Lint, custom hash function ignores notes /// otherwise hash is based on the all the fields pub is_lint: bool, + + /// With `-Ztrack_diagnostics` enabled, + /// we print where in rustc this error was emitted. + pub emitted_at: DiagnosticLocation, +} + +#[derive(Clone, Debug, Encodable, Decodable)] +pub struct DiagnosticLocation { + file: Cow<'static, str>, + line: u32, + col: u32, +} + +impl DiagnosticLocation { + #[track_caller] + fn caller() -> Self { + let loc = Location::caller(); + DiagnosticLocation { file: loc.file().into(), line: loc.line(), col: loc.column() } + } +} + +impl fmt::Display for DiagnosticLocation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}:{}:{}", self.file, self.line, self.col) + } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] @@ -173,10 +199,12 @@ impl StringPart { } impl Diagnostic { + #[track_caller] pub fn new>(level: Level, message: M) -> Self { Diagnostic::new_with_code(level, None, message) } + #[track_caller] pub fn new_with_code>( level: Level, code: Option, @@ -192,6 +220,7 @@ impl Diagnostic { args: Default::default(), sort_span: DUMMY_SP, is_lint: false, + emitted_at: DiagnosticLocation::caller(), } } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 9b41234dcfb..ecf8570e81f 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -133,6 +133,7 @@ mod sealed_level_is_error { impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new_guaranteeing_error, const L: Level>( handler: &'a Handler, message: M, @@ -196,6 +197,7 @@ impl EmissionGuarantee for ErrorGuaranteed { } } + #[track_caller] fn make_diagnostic_builder( handler: &Handler, msg: impl Into, @@ -209,6 +211,7 @@ impl EmissionGuarantee for ErrorGuaranteed { impl<'a> DiagnosticBuilder<'a, ()> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new>( handler: &'a Handler, level: Level, @@ -220,6 +223,7 @@ impl<'a> DiagnosticBuilder<'a, ()> { /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. + #[track_caller] pub(crate) fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> Self { debug!("Created new diagnostic"); Self { @@ -308,6 +312,7 @@ impl EmissionGuarantee for Noted { impl<'a> DiagnosticBuilder<'a, !> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. + #[track_caller] pub(crate) fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); Self::new_diagnostic_fatal(handler, diagnostic) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index cd6413bc3ec..b9b9a59e354 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -16,10 +16,10 @@ use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Styl use crate::styled_buffer::StyledBuffer; use crate::translation::{to_fluent_args, Translate}; use crate::{ - CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler, - LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle, + diagnostic::DiagnosticLocation, CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, + FluentBundle, Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, + SubstitutionHighlight, SuggestionStyle, }; - use rustc_lint_defs::pluralize; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; @@ -64,6 +64,7 @@ impl HumanReadableErrorType { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); @@ -77,6 +78,7 @@ impl HumanReadableErrorType { color, diagnostic_width, macro_backtrace, + track_diagnostics, ) } } @@ -557,6 +559,7 @@ impl Emitter for EmitterWriter { &primary_span, &children, &suggestions, + Some(&diag.emitted_at), ); } @@ -650,6 +653,7 @@ pub struct EmitterWriter { diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } #[derive(Debug)] @@ -669,6 +673,7 @@ impl EmitterWriter { teach: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { let dst = Destination::from_stderr(color_config); EmitterWriter { @@ -681,6 +686,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -694,6 +700,7 @@ impl EmitterWriter { colored: bool, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> EmitterWriter { EmitterWriter { dst: Raw(dst, colored), @@ -705,6 +712,7 @@ impl EmitterWriter { ui_testing: false, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -1327,6 +1335,7 @@ impl EmitterWriter { level: &Level, max_line_num_len: usize, is_secondary: bool, + emitted_at: Option<&DiagnosticLocation>, ) -> io::Result<()> { let mut buffer = StyledBuffer::new(); @@ -1377,7 +1386,6 @@ impl EmitterWriter { } } } - let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp); // Make sure our primary file comes first @@ -1653,6 +1661,12 @@ impl EmitterWriter { } } + if self.track_diagnostics && let Some(tracked) = emitted_at { + let track = format!("-Ztrack-diagnostics: created at {tracked}"); + let len = buffer.num_lines(); + buffer.append(len, &track, Style::NoStyle); + } + // final step: take our styled buffer, render it, then output it emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; @@ -1977,6 +1991,7 @@ impl EmitterWriter { span: &MultiSpan, children: &[SubDiagnostic], suggestions: &[CodeSuggestion], + emitted_at: Option<&DiagnosticLocation>, ) { let max_line_num_len = if self.ui_testing { ANONYMIZED_LINE_NUM.len() @@ -1985,7 +2000,16 @@ impl EmitterWriter { num_decimal_digits(n) }; - match self.emit_message_default(span, message, args, code, level, max_line_num_len, false) { + match self.emit_message_default( + span, + message, + args, + code, + level, + max_line_num_len, + false, + emitted_at, + ) { Ok(()) => { if !children.is_empty() || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden) @@ -2014,6 +2038,7 @@ impl EmitterWriter { &child.level, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", err); } @@ -2030,6 +2055,7 @@ impl EmitterWriter { &Level::Help, max_line_num_len, true, + None, ) { panic!("failed to emit error: {}", e); } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 4cc7be47fc2..c4498eafa4e 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -45,6 +45,7 @@ pub struct JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, } impl JsonEmitter { @@ -57,6 +58,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst: Box::new(io::BufWriter::new(io::stderr())), @@ -69,6 +71,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -79,6 +82,7 @@ impl JsonEmitter { fallback_bundle: LazyFallbackBundle, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); JsonEmitter::stderr( @@ -90,6 +94,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, ) } @@ -103,6 +108,7 @@ impl JsonEmitter { json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, + track_diagnostics: bool, ) -> JsonEmitter { JsonEmitter { dst, @@ -115,6 +121,7 @@ impl JsonEmitter { json_rendered, diagnostic_width, macro_backtrace, + track_diagnostics, } } @@ -350,6 +357,7 @@ impl Diagnostic { false, je.diagnostic_width, je.macro_backtrace, + je.track_diagnostics, ) .ui_testing(je.ui_testing) .emit_diagnostic(diag); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index d940d14e1db..f131468971b 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -59,6 +59,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { HumanReadableErrorType::Short(ColorConfig::Never), None, false, + false, ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 9fafbe4bd40..e3bb50c3d22 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -489,6 +489,8 @@ pub struct HandlerFlags { pub macro_backtrace: bool, /// If true, identical diagnostics are reported only once. pub deduplicate_diagnostics: bool, + /// Track where errors are created. Enabled with `-Ztrack-diagnostics`. + pub track_diagnostics: bool, } impl Drop for HandlerInner { @@ -556,6 +558,7 @@ impl Handler { false, None, flags.macro_backtrace, + flags.track_diagnostics, )); Self::with_emitter_and_flags(emitter, flags) } @@ -661,6 +664,7 @@ impl Handler { /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_diagnostic( &self, msg: impl Into, @@ -674,6 +678,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn( &self, span: impl Into, @@ -690,6 +695,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_span_warn_with_expectation( &self, span: impl Into, @@ -703,6 +709,7 @@ impl Handler { /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_allow( &self, span: impl Into, @@ -716,6 +723,7 @@ impl Handler { /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Also include a code. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_warn_with_code( &self, span: impl Into, @@ -733,6 +741,7 @@ impl Handler { /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Warning(None), msg) } @@ -743,6 +752,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[track_caller] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -759,6 +769,7 @@ impl Handler { /// Construct a builder at the `Expect` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_expect( &self, msg: impl Into, @@ -769,6 +780,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err( &self, span: impl Into, @@ -781,6 +793,7 @@ impl Handler { /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_err_with_code( &self, span: impl Into, @@ -795,6 +808,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, @@ -804,12 +818,14 @@ impl Handler { /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors. #[doc(hidden)] + #[track_caller] pub fn struct_err_lint(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Error { lint: true }, msg) } /// Construct a builder at the `Error` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err_with_code( &self, msg: impl Into, @@ -822,6 +838,7 @@ impl Handler { /// Construct a builder at the `Warn` level with the `msg` and the `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -834,6 +851,7 @@ impl Handler { /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal( &self, span: impl Into, @@ -871,6 +889,7 @@ impl Handler { /// Construct a builder at the `Note` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_note_without_error( &self, msg: impl Into, @@ -885,6 +904,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal_with_code( &self, span: impl Into, @@ -896,6 +916,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err( &self, span: impl Into, @@ -905,6 +926,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_err_with_code( &self, span: impl Into, @@ -918,11 +940,13 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Warning(None), msg), span); } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_warn_with_code( &self, span: impl Into, @@ -932,6 +956,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } + #[track_caller] pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -947,14 +972,17 @@ impl Handler { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). + #[track_caller] pub fn delay_good_path_bug(&self, msg: impl Into) { self.inner.borrow_mut().delay_good_path_bug(msg) } + #[track_caller] pub fn span_bug_no_panic(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Bug, msg), span); } + #[track_caller] pub fn span_note_without_error( &self, span: impl Into, @@ -963,6 +991,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Note, msg), span); } + #[track_caller] pub fn span_note_diag( &self, span: Span, @@ -1449,6 +1478,7 @@ impl HandlerInner { } } + #[track_caller] fn span_bug(&mut self, sp: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); panic::panic_any(ExplicitBug); -- cgit 1.4.1-3-g733a5 From 113e8dfb7293cc070214b42541781b2eeac25ae1 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 22 Oct 2022 18:48:20 +0800 Subject: Port `dead_code` lints to be translatable. --- .../rustc_error_messages/locales/en-US/passes.ftl | 34 ++++ compiler/rustc_errors/src/diagnostic_impls.rs | 32 ++++ compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_passes/src/dead.rs | 175 ++++++++++----------- compiler/rustc_passes/src/errors.rs | 80 +++++++++- .../clone-debug-dead-code-in-the-same-struct.rs | 2 +- ...clone-debug-dead-code-in-the-same-struct.stderr | 2 +- .../multiple-dead-codes-in-the-same-struct.rs | 2 +- .../multiple-dead-codes-in-the-same-struct.stderr | 2 +- src/test/ui/lint/dead-code/tuple-struct-field.rs | 2 +- .../ui/lint/dead-code/tuple-struct-field.stderr | 2 +- 11 files changed, 236 insertions(+), 99 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 4bc6bd9fb22..a5b002fa357 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -671,3 +671,37 @@ passes_missing_const_err = attributes `#[rustc_const_unstable]` and `#[rustc_const_stable]` require the function or method to be `const` .help = make the function or method const .label = attribute specified here + +passes_dead_codes = + { $multiple -> + *[true] multiple {$descr}s are + [false] { $num -> + [one] {$descr} {$name_list} is + *[other] {$descr}s {$name_list} are + } + } never {$participle} + +passes_change_fields_to_be_of_unit_type = + consider changing the { $num -> + [one] field + *[other] fields + } to be of unit type to suppress this warning + while preserving the field numbering, or remove the { $num -> + [one] field + *[other] fields + } + +passes_parent_info = + {$num -> + [one] {$descr} + *[other] {$descr}s + } in this {$parent_descr} + +passes_ignored_derived_impls = + `{$name}` has {$trait_list_len -> + [one] a derived impl + *[other] derived impls + } for the {$trait_list_len -> + [one] trait {$trait_list}, but this is + *[other] traits {$trait_list}, but these are + } intentionally ignored during dead code analysis diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 7640b2919f7..f6fe9192b45 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -11,6 +11,7 @@ use rustc_target::abi::TargetDataLayoutErrors; use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; use std::borrow::Cow; use std::fmt; +use std::fmt::Write; use std::num::ParseIntError; use std::path::{Path, PathBuf}; @@ -170,6 +171,37 @@ impl IntoDiagnosticArg for Level { } } +#[derive(Clone)] +pub struct DiagnosticSymbolList(Vec); + +impl From> for DiagnosticSymbolList { + fn from(v: Vec) -> Self { + DiagnosticSymbolList(v) + } +} + +impl IntoDiagnosticArg for DiagnosticSymbolList { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + // FIXME: replace the logic here with a real list formatter + let symbols = match &self.0[..] { + [symbol] => format!("`{symbol}`"), + [symbol, last] => { + format!("`{symbol}` and `{last}`",) + } + [symbols @ .., last] => { + let mut result = String::new(); + for symbol in symbols { + write!(result, "`{symbol}`, ").unwrap(); + } + write!(result, "and `{last}`").unwrap(); + result + } + [] => unreachable!(), + }; + DiagnosticArgValue::Str(Cow::Owned(symbols)) + } +} + impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> { fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { let mut diag; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0963ea71f80..2c8a70981bc 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -376,7 +376,7 @@ pub use diagnostic::{ DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, }; pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted}; -pub use diagnostic_impls::DiagnosticArgFromDisplay; +pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList}; use std::backtrace::Backtrace; /// A handler deals with errors and other compiler output. diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 6a97ad3fe86..9157c8279a5 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, MultiSpan}; +use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -18,7 +18,10 @@ use rustc_session::lint; use rustc_span::symbol::{sym, Symbol}; use std::mem; -use crate::errors::UselessAssignment; +use crate::errors::{ + ChangeFieldsToBeOfUnitType, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, + UselessAssignment, +}; // Any local node that may call something in its body block should be // explored. For example, if it's a live Node::Item that is a @@ -698,99 +701,89 @@ impl<'tcx> DeadVisitor<'tcx> { parent_item: Option, is_positional: bool, ) { - if let Some(&first_id) = dead_codes.first() { - let tcx = self.tcx; - let names: Vec<_> = dead_codes - .iter() - .map(|&def_id| tcx.item_name(def_id.to_def_id()).to_string()) - .collect(); - let spans: Vec<_> = dead_codes - .iter() - .map(|&def_id| match tcx.def_ident_span(def_id) { - Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()), - None => tcx.def_span(def_id), + let Some(&first_id) = dead_codes.first() else { + return; + }; + let tcx = self.tcx; + let names: Vec<_> = + dead_codes.iter().map(|&def_id| tcx.item_name(def_id.to_def_id())).collect(); + let spans: Vec<_> = dead_codes + .iter() + .map(|&def_id| match tcx.def_ident_span(def_id) { + Some(s) => s.with_ctxt(tcx.def_span(def_id).ctxt()), + None => tcx.def_span(def_id), + }) + .collect(); + + let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); + let num = dead_codes.len(); + let multiple = num > 6; + let name_list = names.into(); + + let lint = if is_positional { + lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS + } else { + lint::builtin::DEAD_CODE + }; + + let parent_info = if let Some(parent_item) = parent_item { + let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id()); + Some(ParentInfo { + num, + descr, + parent_descr, + span: tcx.def_ident_span(parent_item).unwrap(), + }) + } else { + None + }; + + let encl_def_id = parent_item.unwrap_or(first_id); + let ignored_derived_impls = + if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { + let trait_list = ign_traits + .iter() + .map(|(trait_id, _)| self.tcx.item_name(*trait_id)) + .collect::>(); + let trait_list_len = trait_list.len(); + Some(IgnoredDerivedImpls { + name: self.tcx.item_name(encl_def_id.to_def_id()), + trait_list: trait_list.into(), + trait_list_len, }) - .collect(); - - let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); - let span_len = dead_codes.len(); - let names = match &names[..] { - _ if span_len > 6 => String::new(), - [name] => format!("`{name}` "), - [names @ .., last] => { - format!( - "{} and `{last}` ", - names.iter().map(|name| format!("`{name}`")).join(", ") - ) - } - [] => unreachable!(), + } else { + None }; - let msg = format!( - "{these}{descr}{s} {names}{are} never {participle}", - these = if span_len > 6 { "multiple " } else { "" }, - s = pluralize!(span_len), - are = pluralize!("is", span_len), - ); - - tcx.struct_span_lint_hir( - if is_positional { - lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS - } else { - lint::builtin::DEAD_CODE - }, - tcx.hir().local_def_id_to_hir_id(first_id), - MultiSpan::from_spans(spans.clone()), - msg, - |err| { - if is_positional { - err.multipart_suggestion( - &format!( - "consider changing the field{s} to be of unit type to \ - suppress this warning while preserving the field \ - numbering, or remove the field{s}", - s = pluralize!(span_len) - ), - spans.iter().map(|sp| (*sp, "()".to_string())).collect(), - // "HasPlaceholders" because applying this fix by itself isn't - // enough: All constructor calls have to be adjusted as well - Applicability::HasPlaceholders, - ); - } - if let Some(parent_item) = parent_item { - let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id()); - err.span_label( - tcx.def_ident_span(parent_item).unwrap(), - format!("{descr}{s} in this {parent_descr}", s = pluralize!(span_len)), - ); - } + let diag = if is_positional { + MultipleDeadCodes::UnusedTupleStructFields { + multiple, + num, + descr, + participle, + name_list, + change_fields_suggestion: ChangeFieldsToBeOfUnitType { num, spans: spans.clone() }, + parent_info, + ignored_derived_impls, + } + } else { + MultipleDeadCodes::DeadCodes { + multiple, + num, + descr, + participle, + name_list, + parent_info, + ignored_derived_impls, + } + }; - let encl_def_id = parent_item.unwrap_or(first_id); - if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) { - let traits_str = ign_traits - .iter() - .map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id))) - .collect::>() - .join(" and "); - let plural_s = pluralize!(ign_traits.len()); - let article = if ign_traits.len() > 1 { "" } else { "a " }; - let is_are = if ign_traits.len() > 1 { "these are" } else { "this is" }; - let msg = format!( - "`{}` has {}derived impl{} for the trait{} {}, but {} \ - intentionally ignored during dead code analysis", - self.tcx.item_name(encl_def_id.to_def_id()), - article, - plural_s, - plural_s, - traits_str, - is_are - ); - err.note(&msg); - } - err - }, - ); - } + self.tcx.emit_spanned_lint( + lint, + tcx.hir().local_def_id_to_hir_id(first_id), + MultiSpan::from_spans(spans.clone()), + diag, + ); } fn warn_dead_fields_and_variants( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index adaaf539242..d39d7629b28 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,12 +4,16 @@ use std::{ }; use rustc_ast::Label; -use rustc_errors::{error_code, Applicability, ErrorGuaranteed, IntoDiagnostic, MultiSpan}; +use rustc_errors::{ + error_code, Applicability, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan, +}; use rustc_hir::{self as hir, ExprKind, Target}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_errors::{pluralize, AddToDiagnostic, Diagnostic, SubdiagnosticMessage}; + use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] @@ -1449,3 +1453,77 @@ pub struct MissingConstErr { #[label] pub const_span: Span, } + +#[derive(LintDiagnostic)] +pub enum MultipleDeadCodes<'tcx> { + #[diag(passes_dead_codes)] + DeadCodes { + multiple: bool, + num: usize, + descr: &'tcx str, + participle: &'tcx str, + name_list: DiagnosticSymbolList, + #[subdiagnostic] + parent_info: Option>, + #[subdiagnostic] + ignored_derived_impls: Option, + }, + #[diag(passes_dead_codes)] + UnusedTupleStructFields { + multiple: bool, + num: usize, + descr: &'tcx str, + participle: &'tcx str, + name_list: DiagnosticSymbolList, + #[subdiagnostic] + change_fields_suggestion: ChangeFieldsToBeOfUnitType, + #[subdiagnostic] + parent_info: Option>, + #[subdiagnostic] + ignored_derived_impls: Option, + }, +} + +#[derive(Subdiagnostic)] +#[label(passes_parent_info)] +pub struct ParentInfo<'tcx> { + pub num: usize, + pub descr: &'tcx str, + pub parent_descr: &'tcx str, + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[note(passes_ignored_derived_impls)] +pub struct IgnoredDerivedImpls { + pub name: Symbol, + pub trait_list: DiagnosticSymbolList, + pub trait_list_len: usize, +} + +pub struct ChangeFieldsToBeOfUnitType { + pub num: usize, + pub spans: Vec, +} + +// FIXME: Replace this impl with a derive. +impl AddToDiagnostic for ChangeFieldsToBeOfUnitType { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + diag.multipart_suggestion( + &format!( + "consider changing the field{s} to be of unit type to \ + suppress this warning while preserving the field \ + numbering, or remove the field{s}", + s = pluralize!(self.num) + ), + self.spans.iter().map(|sp| (*sp, "()".to_string())).collect(), + // "HasPlaceholders" because applying this fix by itself isn't + // enough: All constructor calls have to be adjusted as well + Applicability::HasPlaceholders, + ); + } +} diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs index 15d06817577..6ab1fb7b039 100644 --- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs +++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.rs @@ -3,7 +3,7 @@ #[derive(Debug)] pub struct Whatever { pub field0: (), - field1: (), //~ ERROR fields `field1`, `field2`, `field3` and `field4` are never read + field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read field2: (), field3: (), field4: (), diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr index 512b870fa4b..7f4f78cebc9 100644 --- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr +++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr @@ -1,4 +1,4 @@ -error: fields `field1`, `field2`, `field3` and `field4` are never read +error: fields `field1`, `field2`, `field3`, and `field4` are never read --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5 | LL | pub struct Whatever { diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs index e3935cf9149..2003e1e293a 100644 --- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs +++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs @@ -7,7 +7,7 @@ struct Bar { b: usize, //~ ERROR field `b` is never read #[deny(dead_code)] c: usize, //~ ERROR fields `c` and `e` are never read - d: usize, //~ WARN fields `d`, `f` and `g` are never read + d: usize, //~ WARN fields `d`, `f`, and `g` are never read #[deny(dead_code)] e: usize, f: usize, diff --git a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr index c0f1ed38f6d..0e5c78a7167 100644 --- a/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr +++ b/src/test/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr @@ -1,4 +1,4 @@ -warning: fields `d`, `f` and `g` are never read +warning: fields `d`, `f`, and `g` are never read --> $DIR/multiple-dead-codes-in-the-same-struct.rs:10:5 | LL | struct Bar { diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs index b15d7063686..14fb30be949 100644 --- a/src/test/ui/lint/dead-code/tuple-struct-field.rs +++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs @@ -11,7 +11,7 @@ struct SingleUnused(i32, [u8; LEN], String); //~| HELP: consider changing the field to be of unit type struct MultipleUnused(i32, f32, String, u8); -//~^ ERROR: fields `0`, `1`, `2` and `3` are never read +//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read //~| NOTE: fields in this struct //~| HELP: consider changing the fields to be of unit type diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.stderr b/src/test/ui/lint/dead-code/tuple-struct-field.stderr index ca0989f5b98..b8ad5cbe4e9 100644 --- a/src/test/ui/lint/dead-code/tuple-struct-field.stderr +++ b/src/test/ui/lint/dead-code/tuple-struct-field.stderr @@ -16,7 +16,7 @@ help: consider changing the field to be of unit type to suppress this warning wh LL | struct SingleUnused(i32, (), String); | ~~ -error: fields `0`, `1`, `2` and `3` are never read +error: fields `0`, `1`, `2`, and `3` are never read --> $DIR/tuple-struct-field.rs:13:23 | LL | struct MultipleUnused(i32, f32, String, u8); -- cgit 1.4.1-3-g733a5 From 854b3166a05916f01b6a7cb9c09fc7c8d26697ad Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 24 Oct 2022 20:52:51 +0200 Subject: Address some comments --- compiler/rustc_errors/src/emitter.rs | 4 ++-- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_session/src/options.rs | 4 ++-- src/librustdoc/core.rs | 4 ++-- src/test/rustdoc-ui/track-diagnostics.rs | 6 ++++++ src/test/rustdoc-ui/track-diagnostics.stderr | 10 ++++++++++ src/test/rustdoc-ui/z-help.stdout | 1 + src/tools/clippy/tests/ui/track-diagnostics.rs | 8 ++++++++ src/tools/clippy/tests/ui/track-diagnostics.stderr | 10 ++++++++++ 9 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc-ui/track-diagnostics.rs create mode 100644 src/test/rustdoc-ui/track-diagnostics.stderr create mode 100644 src/tools/clippy/tests/ui/track-diagnostics.rs create mode 100644 src/tools/clippy/tests/ui/track-diagnostics.stderr (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index b9b9a59e354..b7b8fe3f25a 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -559,7 +559,7 @@ impl Emitter for EmitterWriter { &primary_span, &children, &suggestions, - Some(&diag.emitted_at), + self.track_diagnostics.then_some(&diag.emitted_at), ); } @@ -1661,7 +1661,7 @@ impl EmitterWriter { } } - if self.track_diagnostics && let Some(tracked) = emitted_at { + if let Some(tracked) = emitted_at { let track = format!("-Ztrack-diagnostics: created at {tracked}"); let len = buffer.num_lines(); buffer.append(len, &track, Style::NoStyle); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index da3102ba7b0..0f7220f9f7a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -689,6 +689,7 @@ fn test_unstable_options_tracking_hash() { untracked!(time_llvm_passes, true); untracked!(time_passes, true); untracked!(trace_macros, true); + untracked!(track_diagnostics, false); untracked!(trim_diagnostic_paths, false); untracked!(ui_testing, true); untracked!(unpretty, Some("expanded".to_string())); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index af290931850..5327dea8804 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1585,8 +1585,8 @@ options! { "choose the TLS model to use (`rustc --print tls-models` for details)"), trace_macros: bool = (false, parse_bool, [UNTRACKED], "for every macro invocation, print its name and arguments (default: no)"), - track_diagnostics: bool = (false, parse_bool, [TRACKED], - "Tracks where in rustc a diagnostic was emitted"), + track_diagnostics: bool = (false, parse_bool, [UNTRACKED], + "tracks where in rustc a diagnostic was emitted"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2a61c2451b6..37d934a540b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -172,7 +172,7 @@ pub(crate) fn new_handler( unstable_opts.teach, diagnostic_width, false, - false, + unstable_opts.track_diagnostics, ) .ui_testing(unstable_opts.ui_testing), ) @@ -191,7 +191,7 @@ pub(crate) fn new_handler( json_rendered, diagnostic_width, false, - false, + unstable_opts.track_diagnostics, ) .ui_testing(unstable_opts.ui_testing), ) diff --git a/src/test/rustdoc-ui/track-diagnostics.rs b/src/test/rustdoc-ui/track-diagnostics.rs new file mode 100644 index 00000000000..fc5343a982e --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +struct A; +struct B; +const S: A = B; diff --git a/src/test/rustdoc-ui/track-diagnostics.stderr b/src/test/rustdoc-ui/track-diagnostics.stderr new file mode 100644 index 00000000000..76453cfe220 --- /dev/null +++ b/src/test/rustdoc-ui/track-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:6:14 + | +LL | const S: A = B; + | ^ expected struct `A`, found struct `B` +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index dbf3a8f00ee..07c8793c08b 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -170,6 +170,7 @@ -Z time-passes=val -- measure time of each rustc pass (default: no) -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) + -Z track-diagnostics=val -- Tracks where in rustc a diagnostic was emitted -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs new file mode 100644 index 00000000000..8c96f46d57a --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + +struct A; +struct B; +const S: A = B; + +fn main() {} diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr new file mode 100644 index 00000000000..76453cfe220 --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> $DIR/track-diagnostics.rs:6:14 + | +LL | const S: A = B; + | ^ expected struct `A`, found struct `B` +-Ztrack-diagnostics: created at compiler/rustc_infer/src/infer/error_reporting/mod.rs:2275:31 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From cbeb244b0588f8d442514a2b7ab95a6021f9863f Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 31 Oct 2022 16:14:29 +0100 Subject: Add more track_caller --- compiler/rustc_errors/src/lib.rs | 6 ++++-- compiler/rustc_hir_analysis/src/errors.rs | 1 + compiler/rustc_macros/src/diagnostics/diagnostic.rs | 3 +++ compiler/rustc_metadata/src/errors.rs | 2 ++ compiler/rustc_monomorphize/src/errors.rs | 1 + compiler/rustc_parse/src/errors.rs | 2 ++ compiler/rustc_passes/src/errors.rs | 5 +++++ compiler/rustc_session/src/parse.rs | 6 ++++++ compiler/rustc_session/src/session.rs | 15 +++++++++++++++ compiler/rustc_trait_selection/src/errors.rs | 1 + src/test/ui/track-diagnostics/track.stderr | 2 +- src/test/ui/track-diagnostics/track6.rs | 14 ++++++++++++++ src/test/ui/track-diagnostics/track6.stderr | 13 +++++++++++++ 13 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/track-diagnostics/track6.rs create mode 100644 src/test/ui/track-diagnostics/track6.stderr (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e3bb50c3d22..0c99aef73b6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -763,6 +763,7 @@ impl Handler { /// Construct a builder at the `Allow` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Allow, msg) } @@ -864,6 +865,7 @@ impl Handler { /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal_with_code( &self, span: impl Into, @@ -877,6 +879,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { DiagnosticBuilder::new_fatal(self, msg) } @@ -898,6 +901,7 @@ impl Handler { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); FatalError.raise() @@ -956,7 +960,6 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new_with_code(Warning(None), Some(code), msg), span); } - #[track_caller] pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { self.inner.borrow_mut().span_bug(span, msg) } @@ -972,7 +975,6 @@ impl Handler { // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's // where the explanation of what "good path" is (also, it should be renamed). - #[track_caller] pub fn delay_good_path_bug(&self, msg: impl Into) { self.inner.borrow_mut().delay_good_path_bug(msg) } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 41f73323d9a..39a0231d50d 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -252,6 +252,7 @@ pub struct MissingTypeParams { // Manual implementation of `IntoDiagnostic` to be able to call `span_to_snippet`. impl<'a> IntoDiagnostic<'a> for MissingTypeParams { + #[track_caller] fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 8cf307df5a5..b6759fda3a2 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -69,6 +69,8 @@ impl<'a> DiagnosticDerive<'a> { for @Self where G: rustc_errors::EmissionGuarantee { + + #[track_caller] fn into_diagnostic( self, #handler: &'__diagnostic_handler_sess rustc_errors::Handler @@ -133,6 +135,7 @@ impl<'a> LintDiagnosticDerive<'a> { let diag = &builder.diag; structure.gen_impl(quote! { gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self { + #[track_caller] fn decorate_lint<'__b>( self, #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index dbfa22aaff0..308307d168c 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -578,6 +578,7 @@ pub struct InvalidMetadataFiles { } impl IntoDiagnostic<'_> for InvalidMetadataFiles { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, @@ -606,6 +607,7 @@ pub struct CannotFindCrate { } impl IntoDiagnostic<'_> for CannotFindCrate { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index cf6e18c013b..c50d4fe5a5c 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -45,6 +45,7 @@ pub struct UnusedGenericParams { } impl IntoDiagnostic<'_> for UnusedGenericParams { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 98fee997427..af70300d911 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -930,6 +930,7 @@ pub(crate) struct ExpectedIdentifier { } impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, @@ -977,6 +978,7 @@ pub(crate) struct ExpectedSemi { } impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index ed548341344..21c43c382f2 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -744,6 +744,7 @@ pub struct InvalidAttrAtCrateLevel { } impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, @@ -877,6 +878,7 @@ pub struct BreakNonLoop<'a> { } impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, @@ -1014,6 +1016,7 @@ pub struct NakedFunctionsAsmBlock { } impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, @@ -1137,6 +1140,7 @@ pub struct NoMainErr { } impl<'a> IntoDiagnostic<'a> for NoMainErr { + #[track_caller] fn into_diagnostic( self, handler: &'a rustc_errors::Handler, @@ -1197,6 +1201,7 @@ pub struct DuplicateLangItem { } impl IntoDiagnostic<'_> for DuplicateLangItem { + #[track_caller] fn into_diagnostic( self, handler: &rustc_errors::Handler, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index a199947ebed..f9f4f2979c4 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -97,6 +97,7 @@ pub fn feature_err<'a>( /// /// This variant allows you to control whether it is a library or language feature. /// Almost always, you want to use this for a language feature. If so, prefer `feature_err`. +#[track_caller] pub fn feature_err_issue<'a>( sess: &'a ParseSess, feature: Symbol, @@ -332,6 +333,7 @@ impl ParseSess { self.proc_macro_quoted_spans.lock().clone() } + #[track_caller] pub fn create_err<'a>( &'a self, err: impl IntoDiagnostic<'a>, @@ -339,10 +341,12 @@ impl ParseSess { err.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.create_err(err).emit() } + #[track_caller] pub fn create_warning<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, @@ -350,6 +354,7 @@ impl ParseSess { warning.into_diagnostic(&self.span_diagnostic) } + #[track_caller] pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { self.create_warning(warning).emit() } @@ -377,6 +382,7 @@ impl ParseSess { } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_err( &self, msg: impl Into, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0c04a2f2449..e9835c333e6 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -330,6 +330,7 @@ impl Session { self.diagnostic().struct_warn_with_expectation(msg, id) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_allow>( &self, sp: S, @@ -338,10 +339,12 @@ impl Session { self.diagnostic().struct_span_allow(sp, msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_allow(msg) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_expect( &self, msg: impl Into, @@ -396,6 +399,7 @@ impl Session { self.diagnostic().struct_warn_with_code(msg, code) } #[rustc_lint_diagnostics] + #[track_caller] pub fn struct_span_fatal>( &self, sp: S, @@ -418,6 +422,7 @@ impl Session { } #[rustc_lint_diagnostics] + #[track_caller] pub fn span_fatal>(&self, sp: S, msg: impl Into) -> ! { self.diagnostic().span_fatal(sp, msg) } @@ -490,33 +495,40 @@ impl Session { add_feature_diagnostics(&mut err, &self.parse_sess, feature); err } + #[track_caller] pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.parse_sess.emit_err(err) } + #[track_caller] pub fn create_warning<'a>( &'a self, err: impl IntoDiagnostic<'a, ()>, ) -> DiagnosticBuilder<'a, ()> { self.parse_sess.create_warning(err) } + #[track_caller] pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { self.parse_sess.emit_warning(warning) } + #[track_caller] pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, Noted>, ) -> DiagnosticBuilder<'a, Noted> { self.parse_sess.create_note(note) } + #[track_caller] pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, Noted>) -> Noted { self.parse_sess.emit_note(note) } + #[track_caller] pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, !>, ) -> DiagnosticBuilder<'a, !> { self.parse_sess.create_fatal(fatal) } + #[track_caller] pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! { self.parse_sess.emit_fatal(fatal) } @@ -556,6 +568,7 @@ impl Session { } #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] + #[track_caller] pub fn span_warn>(&self, sp: S, msg: impl Into) { self.diagnostic().span_warn(sp, msg) } @@ -602,6 +615,8 @@ impl Session { pub fn note_without_error(&self, msg: impl Into) { self.diagnostic().note_without_error(msg) } + + #[track_caller] pub fn span_note_without_error>( &self, sp: S, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 61793468594..b64babc9f9e 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -67,6 +67,7 @@ pub struct NegativePositiveConflict<'a> { } impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> { + #[track_caller] fn into_diagnostic( self, handler: &Handler, diff --git a/src/test/ui/track-diagnostics/track.stderr b/src/test/ui/track-diagnostics/track.stderr index d23f625c2d1..ba26cf7c745 100644 --- a/src/test/ui/track-diagnostics/track.stderr +++ b/src/test/ui/track-diagnostics/track.stderr @@ -10,7 +10,7 @@ error[E0268]: `break` outside of a loop | LL | break rust | ^^^^^^^^^^ cannot `break` outside of a loop --Ztrack-diagnostics: created at compiler/rustc_passes/src/errors.rs:LL:CC +-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? diff --git a/src/test/ui/track-diagnostics/track6.rs b/src/test/ui/track-diagnostics/track6.rs new file mode 100644 index 00000000000..307e3101849 --- /dev/null +++ b/src/test/ui/track-diagnostics/track6.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z track-diagnostics +// error-pattern: created at + + + +pub trait Foo { + fn bar(); +} + +impl Foo for T { + default fn bar() {} +} + +fn main() {} diff --git a/src/test/ui/track-diagnostics/track6.stderr b/src/test/ui/track-diagnostics/track6.stderr new file mode 100644 index 00000000000..1c7537633ff --- /dev/null +++ b/src/test/ui/track-diagnostics/track6.stderr @@ -0,0 +1,13 @@ +error[E0658]: specialization is unstable + --> $DIR/track6.rs:11:5 + | +LL | default fn bar() {} + | ^^^^^^^^^^^^^^^^^^^ +-Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:93:5 + | + = note: see issue #31844 for more information + = help: add `#![feature(specialization)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From 4c80f50fc6dce4e35eebe1beaadd5fc3ecfe6f52 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 30 Oct 2022 15:38:37 -0400 Subject: UPDATE - Complete link.rs migration to new diagnostics infraestructure --- compiler/rustc_codegen_ssa/src/back/link.rs | 123 +++++++------------ compiler/rustc_codegen_ssa/src/errors.rs | 130 +++++++++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 51 ++++++++ compiler/rustc_errors/src/diagnostic_impls.rs | 4 +- 4 files changed, 227 insertions(+), 81 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 0dc0dee862c..4c58d0b53f0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -919,29 +919,17 @@ fn link_natively<'a>( ) .is_some(); - sess.note_without_error("`link.exe` returned an unexpected error"); + sess.emit_note(errors::LinkExeUnexpectedError); if is_vs_installed && has_linker { // the linker is broken - sess.note_without_error( - "the Visual Studio build tools may need to be repaired \ - using the Visual Studio installer", - ); - sess.note_without_error( - "or a necessary component may be missing from the \ - \"C++ build tools\" workload", - ); + sess.emit_note(errors::RepairVSBuildTools); + sess.emit_note(errors::MissingCppBuildToolComponent); } else if is_vs_installed { // the linker is not installed - sess.note_without_error( - "in the Visual Studio installer, ensure the \ - \"C++ build tools\" workload is selected", - ); + sess.emit_note(errors::SelectCppBuildToolWorkload); } else { // visual studio is not installed - sess.note_without_error( - "you may need to install Visual Studio build tools with the \ - \"C++ build tools\" workload", - ); + sess.emit_note(errors::VisualStudioNotInstalled); } } } @@ -954,35 +942,20 @@ fn link_natively<'a>( Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; - let mut linker_error = { - if linker_not_found { - sess.struct_err(&format!("linker `{}` not found", linker_path.display())) - } else { - sess.struct_err(&format!( - "could not exec the linker `{}`", - linker_path.display() - )) - } - }; - - linker_error.note(&e.to_string()); - - if !linker_not_found { - linker_error.note(&format!("{:?}", &cmd)); + if linker_not_found { + sess.emit_err(errors::LinkerNotFound { linker_path, error: e }); + } else { + sess.emit_err(errors::UnableToExeLinker { + linker_path, + error: e, + command_formatted: format!("{:?}", &cmd), + }); } - linker_error.emit(); - if sess.target.is_like_msvc && linker_not_found { - sess.note_without_error( - "the msvc targets depend on the msvc linker \ - but `link.exe` was not found", - ); - sess.note_without_error( - "please ensure that Visual Studio 2017 or later, or Build Tools \ - for Visual Studio were installed with the Visual C++ option.", - ); - sess.note_without_error("VS Code is a different product, and is not sufficient."); + sess.emit_note(errors::MsvcMissingLinker); + sess.emit_note(errors::CheckInstalledVisualStudio); + sess.emit_note(errors::UnsufficientVSCodeProduct); } sess.abort_if_errors(); } @@ -1007,15 +980,13 @@ fn link_natively<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_warn(&format!( - "processing debug info with `dsymutil` failed: {}", - prog.status - )) - .note(&escape_string(&output)) - .emit(); + sess.emit_warning(errors::ProcessingDymutilFailed { + status: prog.status, + output: escape_string(&output), + }); } } - Err(e) => sess.fatal(&format!("unable to run `dsymutil`: {}", e)), + Err(error) => sess.emit_fatal(errors::UnableToRunDsymutil { error }), } } @@ -1092,21 +1063,21 @@ fn strip_symbols_with_external_utility<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_warn(&format!( - "stripping debug info with `{}` failed: {}", - util, prog.status - )) - .note(&escape_string(&output)) - .emit(); + sess.emit_warning(errors::StrippingDebuInfoFailed { + util, + status: prog.status, + output: escape_string(&output), + }); } } - Err(e) => sess.fatal(&format!("unable to run `{}`: {}", util, e)), + Err(error) => sess.emit_fatal(errors::UnableToRun { util, error }), } } fn escape_string(s: &[u8]) -> String { match str::from_utf8(s) { Ok(s) => s.to_owned(), + // FIXME: return a type that can conform to IntoDiagnosticArg Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()), } } @@ -1251,7 +1222,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { )), (Some(linker), None) => { let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker") + sess.emit_fatal(errors::LinkerFileStem); }); let flavor = if stem == "emcc" { @@ -1378,13 +1349,9 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { }) .collect(); if !lib_args.is_empty() { - sess.note_without_error( - "Link against the following native artifacts when linking \ - against this static library. The order and any duplication \ - can be significant on some platforms.", - ); + sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability - sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" "))); + sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") }); } } @@ -1688,14 +1655,14 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty match (crate_type, &sess.target.link_script) { (CrateType::Cdylib | CrateType::Executable, Some(script)) => { if !sess.target.linker_flavor.is_gnu() { - sess.fatal("can only use link script when linking with GNU-like linker"); + sess.emit_fatal(errors::LinkScriptUnavailable); } let file_name = ["rustc", &sess.target.llvm_target, "linkfile.ld"].join("-"); let path = tmpdir.join(file_name); - if let Err(e) = fs::write(&path, script.as_ref()) { - sess.fatal(&format!("failed to write link script to {}: {}", path.display(), e)); + if let Err(error) = fs::write(&path, script.as_ref()) { + sess.emit_fatal(errors::LinkScriptWriteFailure { path, error }); } cmd.arg("--script"); @@ -1841,8 +1808,8 @@ fn add_linked_symbol_object( let path = tmpdir.join("symbols.o"); let result = std::fs::write(&path, file.write().unwrap()); - if let Err(e) = result { - sess.fatal(&format!("failed to write {}: {}", path.display(), e)); + if let Err(error) = result { + sess.emit_fatal(errors::FailedToWrite { path, error }); } cmd.add_object(&path); } @@ -2299,14 +2266,10 @@ fn collect_natvis_visualizers( visualizer_paths.push(visualizer_out_file); } Err(error) => { - sess.warn( - format!( - "Unable to write debugger visualizer file `{}`: {} ", - visualizer_out_file.display(), - error - ) - .as_str(), - ); + sess.emit_warning(errors::UnableToWriteDebuggerVisualizer { + path: visualizer_out_file, + error, + }); } }; } @@ -2641,7 +2604,7 @@ fn add_upstream_rust_crates<'a>( || !codegen_results.crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); - if let Err(e) = archive.add_archive( + if let Err(error) = archive.add_archive( cratepath, Box::new(move |f| { if f == METADATA_FILENAME { @@ -2681,7 +2644,7 @@ fn add_upstream_rust_crates<'a>( false }), ) { - sess.fatal(&format!("failed to build archive from rlib: {}", e)); + sess.emit_fatal(errors::RlibArchiveBuildFailure { error }); } if archive.build(&dst) { link_upstream(&dst); @@ -2919,7 +2882,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { } } } else { - sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc"); + sess.emit_fatal(errors::OptionGccOnly); } } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index ebb531f1c43..71fac123725 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -354,3 +354,133 @@ impl IntoDiagnostic<'_> for LinkingFailed<'_> { diag } } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_exe_unexpected_error)] +pub struct LinkExeUnexpectedError; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_repair_vs_build_tools)] +pub struct RepairVSBuildTools; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_missing_cpp_build_tool_component)] +pub struct MissingCppBuildToolComponent; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_select_cpp_build_tool_workload)] +pub struct SelectCppBuildToolWorkload; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_visual_studio_not_installed)] +pub struct VisualStudioNotInstalled; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_linker_not_found)] +#[note] +pub struct LinkerNotFound { + pub linker_path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_exe_linker)] +#[note] +#[note(command_note)] +pub struct UnableToExeLinker { + pub linker_path: PathBuf, + pub error: Error, + pub command_formatted: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_msvc_missing_linker)] +pub struct MsvcMissingLinker; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_check_installed_visual_studio)] +pub struct CheckInstalledVisualStudio; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsufficient_vs_code_product)] +pub struct UnsufficientVSCodeProduct; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_processing_dymutil_failed)] +#[note] +pub struct ProcessingDymutilFailed { + pub status: ExitStatus, + pub output: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_run_dsymutil)] +#[note] +pub struct UnableToRunDsymutil { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_stripping_debu_info_failed)] +#[note] +pub struct StrippingDebuInfoFailed<'a> { + pub util: &'a str, + pub status: ExitStatus, + pub output: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_run)] +pub struct UnableToRun<'a> { + pub util: &'a str, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_linker_file_stem)] +pub struct LinkerFileStem; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_static_library_native_artifacts)] +pub struct StaticLibraryNativeArtifacts; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_native_static_libs)] +pub struct NativeStaticLibs { + pub arguments: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_script_unavailable)] +pub struct LinkScriptUnavailable; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_link_script_write_failure)] +pub struct LinkScriptWriteFailure { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_failed_to_write)] +pub struct FailedToWrite { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unable_to_write_debugger_visualizer)] +pub struct UnableToWriteDebuggerVisualizer { + pub path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_rlib_archive_build_failure)] +pub struct RlibArchiveBuildFailure { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_option_gcc_only)] +pub struct OptionGccOnly; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 966a421bcf0..2e5c72ee645 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -119,3 +119,54 @@ codegen_ssa_thorin_object_read = {$error} codegen_ssa_thorin_object_write = {$error} codegen_ssa_thorin_gimli_read = {$error} codegen_ssa_thorin_gimli_write = {$error} + +codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error + +codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer + +codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload + +codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected + +codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload + +codegen_ssa_linker_not_found = linker `{$linker_path}` not found + .note = {$error} + +codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}` + .note = {$error} + .command_note = {$command_formatted} + +codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found + +codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. + +codegen_ssa_unsufficient_vs_code_product = VS Code is a different product, and is not sufficient. + +codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} + .note = {$output} + +codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} + +codegen_ssa_stripping_debu_info_failed = stripping debug info with `{$util}` failed: {$status} + .note = {$output} + +codegen_ssa_unable_to_run = unable to run `{$util}`: {$error} + +codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker + +codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. + +codegen_ssa_native_static_libs = native-static-libs: {$arguments} + +codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker + +codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} + +codegen_ssa_failed_to_write = failed to write {$path}: {$error} + +codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error} + +codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error} + +codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 7640b2919f7..4f32e236b2d 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -13,6 +13,7 @@ use std::borrow::Cow; use std::fmt; use std::num::ParseIntError; use std::path::{Path, PathBuf}; +use std::process::ExitStatus; pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display); @@ -66,7 +67,8 @@ into_diagnostic_arg_using_display!( ParseIntError, StackProtector, &TargetTriple, - SplitDebuginfo + SplitDebuginfo, + ExitStatus, ); impl IntoDiagnosticArg for bool { -- cgit 1.4.1-3-g733a5 From 540c3f94d71879f413a151bc8c83c20c10b386dc Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Fri, 4 Nov 2022 01:16:16 -0400 Subject: UPDATE - accept dyn error and make Box conform to IntoDiagnosticArg --- compiler/rustc_codegen_ssa/src/back/archive.rs | 29 +++++++++++++------------- compiler/rustc_codegen_ssa/src/errors.rs | 14 ++++++------- compiler/rustc_errors/src/diagnostic_impls.rs | 1 + 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 9113ddab048..18789d00fd3 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -35,30 +35,29 @@ pub trait ArchiveBuilderBuilder { outdir: &Path, bundled_lib_file_names: &FxHashSet, ) -> Result<(), ExtractBundledLibsError<'_>> { - let archive_map = - unsafe { - Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError::OpenFile { - rlib, - error: e.to_string(), - })?) - .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: e.to_string() })? - }; + let archive_map = unsafe { + Mmap::map( + File::open(rlib) + .map_err(|e| ExtractBundledLibsError::OpenFile { rlib, error: Box::new(e) })?, + ) + .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: Box::new(e) })? + }; let archive = ArchiveFile::parse(&*archive_map) - .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: Box::new(e) })?; for entry in archive.members() { let entry = entry - .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: e.to_string() })?; - let data = entry.data(&*archive_map).map_err(|e| { - ExtractBundledLibsError::ArchiveMember { rlib, error: e.to_string() } - })?; + .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: Box::new(e) })?; + let data = entry + .data(&*archive_map) + .map_err(|e| ExtractBundledLibsError::ArchiveMember { rlib, error: Box::new(e) })?; let name = std::str::from_utf8(entry.name()) - .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: Box::new(e) })?; if !bundled_lib_file_names.contains(&Symbol::intern(name)) { continue; // We need to extract only native libraries. } std::fs::write(&outdir.join(&name), data) - .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: e.to_string() })?; + .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: Box::new(e) })?; } Ok(()) } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 265f466f2ca..36c94462b0b 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -488,25 +488,25 @@ pub struct OptionGccOnly; #[derive(Diagnostic)] pub enum ExtractBundledLibsError<'a> { #[diag(codegen_ssa_extract_bundled_libs_open_file)] - OpenFile { rlib: &'a Path, error: String }, + OpenFile { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_mmap_file)] - MmapFile { rlib: &'a Path, error: String }, + MmapFile { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_parse_archive)] - ParseArchive { rlib: &'a Path, error: String }, + ParseArchive { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_read_entry)] - ReadEntry { rlib: &'a Path, error: String }, + ReadEntry { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_archive_member)] - ArchiveMember { rlib: &'a Path, error: String }, + ArchiveMember { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_convert_name)] - ConvertName { rlib: &'a Path, error: String }, + ConvertName { rlib: &'a Path, error: Box }, #[diag(codegen_ssa_extract_bundled_libs_write_file)] - WriteFile { rlib: &'a Path, error: String }, + WriteFile { rlib: &'a Path, error: Box }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 4f32e236b2d..83a3211c63b 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -59,6 +59,7 @@ into_diagnostic_arg_using_display!( i128, u128, std::io::Error, + std::boxed::Box, std::num::NonZeroU32, hir::Target, Edition, -- cgit 1.4.1-3-g733a5