summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_errors/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_errors/src/lib.rs')
-rw-r--r--compiler/rustc_errors/src/lib.rs62
1 files changed, 39 insertions, 23 deletions
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"),