diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_errors | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_errors')
-rw-r--r-- | compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 16 | ||||
-rw-r--r-- | compiler/rustc_errors/src/diagnostic_impls.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_errors/src/emitter.rs | 43 | ||||
-rw-r--r-- | compiler/rustc_errors/src/json.rs | 24 | ||||
-rw-r--r-- | compiler/rustc_errors/src/lib.rs | 62 |
6 files changed, 112 insertions, 40 deletions
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index a88fba6da..203e52912 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -91,7 +91,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType { } Level::Warning(_) => AnnotationType::Warning, Level::Note | Level::OnceNote => AnnotationType::Note, - Level::Help => AnnotationType::Help, + Level::Help | Level::OnceHelp => AnnotationType::Help, // FIXME(#59346): Not sure how to map this level Level::FailureNote => AnnotationType::Error, Level::Allow => panic!("Should not call with Allow"), @@ -169,7 +169,8 @@ impl AnnotateSnippetEmitterWriter { .map(|line| { // Ensure the source file is present before we try // to load a string from it. - source_map.ensure_source_file_source_present(file.clone()); + // FIXME(#115869): support -Z ignore-directory-in-diagnostics-source-blocks + source_map.ensure_source_file_source_present(&file); ( format!("{}", source_map.filename_for_diagnostics(&file.name)), source_string(file.clone(), &line), diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index a96e317df..470f318eb 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -151,7 +151,12 @@ impl fmt::Display for DiagnosticLocation { #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] pub enum DiagnosticId { Error(String), - Lint { name: String, has_future_breakage: bool, is_force_warn: bool }, + Lint { + name: String, + /// Indicates whether this lint should show up in cargo's future breakage report. + has_future_breakage: bool, + is_force_warn: bool, + }, } /// A "sub"-diagnostic attached to a parent diagnostic. @@ -270,6 +275,7 @@ impl Diagnostic { | Level::Note | Level::OnceNote | Level::Help + | Level::OnceHelp | Level::Allow | Level::Expect(_) => false, } @@ -300,6 +306,7 @@ impl Diagnostic { } } + /// Indicates whether this diagnostic should show up in cargo's future breakage report. pub fn has_future_breakage(&self) -> bool { match self.code { Some(DiagnosticId::Lint { has_future_breakage, .. }) => has_future_breakage, @@ -532,6 +539,13 @@ impl Diagnostic { self } + /// Prints the span with a help above it. + /// This is like [`Diagnostic::help()`], but it gets its own span. + pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { + self.sub(Level::OnceHelp, msg, MultiSpan::new(), None); + self + } + /// Add a help message attached to this diagnostic with a customizable highlighted message. pub fn highlighted_help(&mut self, msg: Vec<(String, Style)>) -> &mut Self { self.sub_with_highlights(Level::Help, msg, MultiSpan::new(), None); diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index a170e3a89..4f77f09b2 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -161,7 +161,7 @@ impl IntoDiagnosticArg for hir::ConstContext { DiagnosticArgValue::Str(Cow::Borrowed(match self { hir::ConstContext::ConstFn => "const_fn", hir::ConstContext::Static(_) => "static", - hir::ConstContext::Const => "const", + hir::ConstContext::Const { .. } => "const", })) } } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 0cae06881..d322cbe9d 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -8,7 +8,7 @@ //! The output types are defined in `rustc_session::config::ErrorOutputType`. use rustc_span::source_map::SourceMap; -use rustc_span::{FileLines, SourceFile, Span}; +use rustc_span::{FileLines, FileName, SourceFile, Span}; use crate::snippet::{ Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, @@ -24,7 +24,7 @@ use rustc_lint_defs::pluralize; use derive_setters::Setters; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{DynSend, IntoDynSyncSend, Lrc}; use rustc_error_messages::{FluentArgs, SpanLabel}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; @@ -188,6 +188,8 @@ impl Margin { const ANONYMIZED_LINE_NUM: &str = "LL"; +pub type DynEmitter = dyn Emitter + DynSend; + /// Emitter trait for emitting errors. pub trait Emitter: Translate { /// Emit a structured diagnostic. @@ -625,7 +627,7 @@ impl ColorConfig { #[derive(Setters)] pub struct EmitterWriter { #[setters(skip)] - dst: Destination, + dst: IntoDynSyncSend<Destination>, sm: Option<Lrc<SourceMap>>, fluent_bundle: Option<Lrc<FluentBundle>>, #[setters(skip)] @@ -633,6 +635,7 @@ pub struct EmitterWriter { short_message: bool, teach: bool, ui_testing: bool, + ignored_directories_in_source_blocks: Vec<String>, diagnostic_width: Option<usize>, macro_backtrace: bool, @@ -655,13 +658,14 @@ impl EmitterWriter { fn create(dst: Destination, fallback_bundle: LazyFallbackBundle) -> EmitterWriter { EmitterWriter { - dst, + dst: IntoDynSyncSend(dst), sm: None, fluent_bundle: None, fallback_bundle, short_message: false, teach: false, ui_testing: false, + ignored_directories_in_source_blocks: Vec::new(), diagnostic_width: None, macro_backtrace: false, track_diagnostics: false, @@ -1191,7 +1195,7 @@ impl EmitterWriter { let will_be_emitted = |span: Span| { !span.is_dummy() && { let file = sm.lookup_source_file(span.hi()); - sm.ensure_source_file_source_present(file) + should_show_source_code(&self.ignored_directories_in_source_blocks, sm, &file) } }; @@ -1386,7 +1390,11 @@ impl EmitterWriter { // Print out the annotate source lines that correspond with the error for annotated_file in annotated_files { // we can't annotate anything if the source is unavailable. - if !sm.ensure_source_file_source_present(annotated_file.file.clone()) { + if !should_show_source_code( + &self.ignored_directories_in_source_blocks, + sm, + &annotated_file.file, + ) { if !self.short_message { // We'll just print an unannotated message. for (annotation_id, line) in annotated_file.lines.iter().enumerate() { @@ -2346,7 +2354,13 @@ impl FileWithAnnotatedLines { } let label = label.as_ref().map(|m| { - emitter.translate_message(m, args).map_err(Report::new).unwrap().to_string() + normalize_whitespace( + &emitter + .translate_message(m, &args) + .map_err(Report::new) + .unwrap() + .to_string(), + ) }); if lo.line != hi.line { @@ -2729,3 +2743,18 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool { // bug, but be defensive against that here. && found != suggested } + +pub(crate) fn should_show_source_code( + ignored_directories: &[String], + sm: &SourceMap, + file: &SourceFile, +) -> bool { + if !sm.ensure_source_file_source_present(file) { + return false; + } + + let FileName::Real(name) = &file.name else { return true }; + name.local_path() + .map(|path| ignored_directories.iter().all(|dir| !path.starts_with(dir))) + .unwrap_or(true) +} diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index b8f58e305..0cb75c71b 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -12,7 +12,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use termcolor::{ColorSpec, WriteColor}; -use crate::emitter::{Emitter, HumanReadableErrorType}; +use crate::emitter::{should_show_source_code, Emitter, HumanReadableErrorType}; use crate::registry::Registry; use crate::translation::{to_fluent_args, Translate}; use crate::DiagnosticId; @@ -22,7 +22,7 @@ use crate::{ }; use rustc_lint_defs::Applicability; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_error_messages::FluentArgs; use rustc_span::hygiene::ExpnData; use rustc_span::Span; @@ -38,13 +38,14 @@ use serde::Serialize; mod tests; pub struct JsonEmitter { - dst: Box<dyn Write + Send>, + dst: IntoDynSyncSend<Box<dyn Write + Send>>, registry: Option<Registry>, sm: Lrc<SourceMap>, fluent_bundle: Option<Lrc<FluentBundle>>, fallback_bundle: LazyFallbackBundle, pretty: bool, ui_testing: bool, + ignored_directories_in_source_blocks: Vec<String>, json_rendered: HumanReadableErrorType, diagnostic_width: Option<usize>, macro_backtrace: bool, @@ -66,13 +67,14 @@ impl JsonEmitter { terminal_url: TerminalUrl, ) -> JsonEmitter { JsonEmitter { - dst: Box::new(io::BufWriter::new(io::stderr())), + dst: IntoDynSyncSend(Box::new(io::BufWriter::new(io::stderr()))), registry, sm: source_map, fluent_bundle, fallback_bundle, pretty, ui_testing: false, + ignored_directories_in_source_blocks: Vec::new(), json_rendered, diagnostic_width, macro_backtrace, @@ -120,13 +122,14 @@ impl JsonEmitter { terminal_url: TerminalUrl, ) -> JsonEmitter { JsonEmitter { - dst, + dst: IntoDynSyncSend(dst), registry, sm: source_map, fluent_bundle, fallback_bundle, pretty, ui_testing: false, + ignored_directories_in_source_blocks: Vec::new(), json_rendered, diagnostic_width, macro_backtrace, @@ -138,6 +141,10 @@ impl JsonEmitter { pub fn ui_testing(self, ui_testing: bool) -> Self { Self { ui_testing, ..self } } + + pub fn ignored_directories_in_source_blocks(self, value: Vec<String>) -> Self { + Self { ignored_directories_in_source_blocks: value, ..self } + } } impl Translate for JsonEmitter { @@ -381,6 +388,7 @@ impl Diagnostic { .track_diagnostics(je.track_diagnostics) .terminal_url(je.terminal_url) .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) .emit_diagnostic(diag); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); let output = String::from_utf8(output).unwrap(); @@ -558,7 +566,11 @@ impl DiagnosticSpanLine { .span_to_lines(span) .map(|lines| { // We can't get any lines if the source is unavailable. - if !je.sm.ensure_source_file_source_present(lines.file.clone()) { + if !should_show_source_code( + &je.ignored_directories_in_source_blocks, + &je.sm, + &lines.file, + ) { return vec![]; } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 34518b537..b747a62b8 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -15,7 +15,7 @@ #![feature(box_patterns)] #![feature(error_reporter)] #![allow(incomplete_features)] -#![cfg_attr(not(bootstrap), allow(internal_features))] +#![allow(internal_features)] #[macro_use] extern crate rustc_macros; @@ -30,11 +30,11 @@ pub use emitter::ColorConfig; use rustc_lint_defs::LintExpectationId; use Level::*; -use emitter::{is_case_difference, Emitter, EmitterWriter}; +use emitter::{is_case_difference, DynEmitter, Emitter, EmitterWriter}; use registry::Registry; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; -use rustc_data_structures::sync::{self, IntoDynSyncSend, Lock, Lrc}; +use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, @@ -44,7 +44,7 @@ use rustc_fluent_macro::fluent_messages; pub use rustc_lint_defs::{pluralize, Applicability}; use rustc_span::source_map::SourceMap; pub use rustc_span::ErrorGuaranteed; -use rustc_span::{Loc, Span}; +use rustc_span::{Loc, Span, DUMMY_SP}; use std::borrow::Cow; use std::error::Report; @@ -55,7 +55,9 @@ use std::num::NonZeroUsize; use std::panic; use std::path::{Path, PathBuf}; -use termcolor::{Color, ColorSpec}; +// Used by external projects such as `rust-gpu`. +// See https://github.com/rust-lang/rust/pull/115393. +pub use termcolor::{Color, ColorSpec, WriteColor}; pub mod annotate_snippet_emitter_writer; mod diagnostic; @@ -197,8 +199,14 @@ impl CodeSuggestion { use rustc_span::{CharPos, Pos}; - /// Append to a buffer the remainder of the line of existing source code, and return the - /// count of lines that have been added for accurate highlighting. + /// Extracts a substring from the provided `line_opt` based on the specified low and high indices, + /// appends it to the given buffer `buf`, and returns the count of newline characters in the substring + /// for accurate highlighting. + /// If `line_opt` is `None`, a newline character is appended to the buffer, and 0 is returned. + /// + /// ## Returns + /// + /// The count of newline characters in the extracted substring. fn push_trailing( buf: &mut String, line_opt: Option<&Cow<'_, str>>, @@ -206,22 +214,30 @@ impl CodeSuggestion { hi_opt: Option<&Loc>, ) -> usize { let mut line_count = 0; + // Convert CharPos to Usize, as CharPose is character offset + // Extract low index and high index let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi| hi.col.to_usize())); if let Some(line) = line_opt { if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) { + // Get high index while account for rare unicode and emoji with char_indices let hi_opt = hi_opt.and_then(|hi| line.char_indices().map(|(i, _)| i).nth(hi)); match hi_opt { + // If high index exist, take string from low to high index Some(hi) if hi > lo => { + // count how many '\n' exist line_count = line[lo..hi].matches('\n').count(); buf.push_str(&line[lo..hi]) } Some(_) => (), + // If high index absence, take string from low index till end string.len None => { + // count how many '\n' exist line_count = line[lo..].matches('\n').count(); buf.push_str(&line[lo..]) } } } + // If high index is None if hi_opt.is_none() { buf.push('\n'); } @@ -257,7 +273,7 @@ impl CodeSuggestion { assert!(!lines.lines.is_empty() || bounding_span.is_dummy()); // We can't splice anything if the source is unavailable. - if !sm.ensure_source_file_source_present(lines.file.clone()) { + if !sm.ensure_source_file_source_present(&lines.file) { return None; } @@ -414,7 +430,7 @@ struct HandlerInner { err_count: usize, warn_count: usize, deduplicated_err_count: usize, - emitter: IntoDynSyncSend<Box<dyn Emitter + sync::Send>>, + emitter: Box<DynEmitter>, delayed_span_bugs: Vec<DelayedDiagnostic>, delayed_good_path_bugs: Vec<DelayedDiagnostic>, /// This flag indicates that an expected diagnostic was emitted and suppressed. @@ -503,7 +519,7 @@ pub struct HandlerFlags { /// If false, warning-level lints are suppressed. /// (rustc: see `--allow warnings` and `--cap-lints`) pub can_emit_warnings: bool, - /// If true, error-level diagnostics are upgraded to bug-level. + /// If Some, the Nth error-level diagnostic is upgraded to bug-level. /// (rustc: see `-Z treat-err-as-bug`) pub treat_err_as_bug: Option<NonZeroUsize>, /// If true, immediately emit diagnostics that would otherwise be buffered. @@ -580,7 +596,7 @@ impl Handler { self } - pub fn with_emitter(emitter: Box<dyn Emitter + sync::Send>) -> Self { + pub fn with_emitter(emitter: Box<DynEmitter>) -> Self { Self { inner: Lock::new(HandlerInner { flags: HandlerFlags { can_emit_warnings: true, ..Default::default() }, @@ -589,7 +605,7 @@ impl Handler { warn_count: 0, deduplicated_err_count: 0, deduplicated_warn_count: 0, - emitter: IntoDynSyncSend(emitter), + emitter, delayed_span_bugs: Vec::new(), delayed_good_path_bugs: Vec::new(), suppressed_expected_diag: false, @@ -1374,7 +1390,7 @@ impl HandlerInner { debug!(?self.emitted_diagnostics); let already_emitted_sub = |sub: &mut SubDiagnostic| { debug!(?sub); - if sub.level != Level::OnceNote { + if sub.level != Level::OnceNote && sub.level != Level::OnceHelp { return false; } let mut hasher = StableHasher::new(); @@ -1703,19 +1719,17 @@ impl HandlerInner { match ( self.err_count() + self.lint_err_count, self.delayed_bug_count(), - self.flags.treat_err_as_bug.map(|c| c.get()).unwrap_or(0), + self.flags.treat_err_as_bug.map(|c| c.get()).unwrap(), ) { (1, 0, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"), (0, 1, 1) => panic!("aborting due delayed bug with `-Z treat-err-as-bug=1`"), - (count, delayed_count, as_bug) => { + (count, delayed_count, val) => { if delayed_count > 0 { panic!( - "aborting after {count} errors and {delayed_count} delayed bugs due to `-Z treat-err-as-bug={as_bug}`", + "aborting after {count} errors and {delayed_count} delayed bugs due to `-Z treat-err-as-bug={val}`", ) } else { - panic!( - "aborting after {count} errors due to `-Z treat-err-as-bug={as_bug}`", - ) + panic!("aborting after {count} errors due to `-Z treat-err-as-bug={val}`") } } } @@ -1738,7 +1752,7 @@ impl DelayedDiagnostic { BacktraceStatus::Captured => { let inner = &self.inner; self.inner.subdiagnostic(DelayedAtWithNewline { - span: inner.span.primary_span().unwrap(), + span: inner.span.primary_span().unwrap_or(DUMMY_SP), emitted_at: inner.emitted_at.clone(), note: self.note, }); @@ -1748,7 +1762,7 @@ impl DelayedDiagnostic { _ => { let inner = &self.inner; self.inner.subdiagnostic(DelayedAtWithoutNewline { - span: inner.span.primary_span().unwrap(), + span: inner.span.primary_span().unwrap_or(DUMMY_SP), emitted_at: inner.emitted_at.clone(), note: self.note, }); @@ -1776,6 +1790,8 @@ pub enum Level { /// A note that is only emitted once. OnceNote, Help, + /// A help that is only emitted once. + OnceHelp, FailureNote, Allow, Expect(LintExpectationId), @@ -1800,7 +1816,7 @@ impl Level { Note | OnceNote => { spec.set_fg(Some(Color::Green)).set_intense(true); } - Help => { + Help | OnceHelp => { spec.set_fg(Some(Color::Cyan)).set_intense(true); } FailureNote => {} @@ -1815,7 +1831,7 @@ impl Level { Fatal | Error { .. } => "error", Warning(_) => "warning", Note | OnceNote => "note", - Help => "help", + Help | OnceHelp => "help", FailureNote => "failure-note", Allow => panic!("Shouldn't call on allowed error"), Expect(_) => panic!("Shouldn't call on expected error"), |