Skip to content

Commit

Permalink
Filter OnceNote in diagnostic infra.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Mar 20, 2022
1 parent 056951d commit 0b49d05
Show file tree
Hide file tree
Showing 29 changed files with 183 additions and 282 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn annotation_type_for_level(level: Level) -> AnnotationType {
AnnotationType::Error
}
Level::Warning => AnnotationType::Warning,
Level::Note => AnnotationType::Note,
Level::Note | Level::OnceNote => AnnotationType::Note,
Level::Help => AnnotationType::Help,
// FIXME(#59346): Not sure how to map this level
Level::FailureNote => AnnotationType::Error,
Expand Down
21 changes: 20 additions & 1 deletion compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ impl Diagnostic {
| Level::Error { .. }
| Level::FailureNote => true,

Level::Warning | Level::Note | Level::Help | Level::Allow | Level::Expect(_) => false,
Level::Warning
| Level::Note
| Level::OnceNote
| Level::Help
| Level::Allow
| Level::Expect(_) => false,
}
}

Expand Down Expand Up @@ -333,13 +338,27 @@ impl Diagnostic {
self
}

/// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn note_once(&mut self, msg: &str) -> &mut Self {
self.sub(Level::OnceNote, msg, MultiSpan::new(), None);
self
}

/// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn span_note<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
self.sub(Level::Note, msg, sp.into(), None);
self
}

/// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn span_note_once<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
self.sub(Level::OnceNote, msg, sp.into(), None);
self
}

/// Add a warning attached to this diagnostic.
pub fn warn(&mut self, msg: &str) -> &mut Self {
self.sub(Level::Warning, msg, MultiSpan::new(), None);
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,17 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
) -> &mut Self);

forward!(pub fn note(&mut self, msg: &str) -> &mut Self);
forward!(pub fn note_once(&mut self, msg: &str) -> &mut Self);
forward!(pub fn span_note(
&mut self,
sp: impl Into<MultiSpan>,
msg: &str,
) -> &mut Self);
forward!(pub fn span_note_once(
&mut self,
sp: impl Into<MultiSpan>,
msg: &str,
) -> &mut Self);
forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
forward!(pub fn span_warn(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> &mut Self);
forward!(pub fn help(&mut self, msg: &str) -> &mut Self);
Expand Down
25 changes: 22 additions & 3 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(crate_visibility_modifier)]
#![feature(drain_filter)]
#![feature(backtrace)]
#![feature(if_let_guard)]
#![feature(let_else)]
Expand Down Expand Up @@ -1070,7 +1071,23 @@ impl HandlerInner {
// Only emit the diagnostic if we've been asked to deduplicate and
// haven't already emitted an equivalent diagnostic.
if !(self.flags.deduplicate_diagnostics && already_emitted(self)) {
self.emitter.emit_diagnostic(diagnostic);
debug!(?diagnostic);
debug!(?self.emitted_diagnostics);
let already_emitted_sub = |sub: &mut SubDiagnostic| {
debug!(?sub);
if sub.level != Level::OnceNote {
return false;
}
let mut hasher = StableHasher::new();
sub.hash(&mut hasher);
let diagnostic_hash = hasher.finish();
debug!(?diagnostic_hash);
!self.emitted_diagnostics.insert(diagnostic_hash)
};

diagnostic.children.drain_filter(already_emitted_sub).for_each(|_| {});

self.emitter.emit_diagnostic(&diagnostic);
if diagnostic.is_error() {
self.deduplicated_err_count += 1;
} else if diagnostic.level == Warning {
Expand Down Expand Up @@ -1350,6 +1367,8 @@ pub enum Level {
},
Warning,
Note,
/// A note that is only emitted once.
OnceNote,
Help,
FailureNote,
Allow,
Expand All @@ -1372,7 +1391,7 @@ impl Level {
Warning => {
spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows));
}
Note => {
Note | OnceNote => {
spec.set_fg(Some(Color::Green)).set_intense(true);
}
Help => {
Expand All @@ -1389,7 +1408,7 @@ impl Level {
Bug | DelayedBug => "error: internal compiler error",
Fatal | Error { .. } => "error",
Warning => "warning",
Note => "note",
Note | OnceNote => "note",
Help => "help",
FailureNote => "failure-note",
Allow => panic!("Shouldn't call on allowed error"),
Expand Down
54 changes: 16 additions & 38 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_session::lint::{
builtin::{self, FORBIDDEN_LINT_GROUPS},
FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId,
};
use rustc_session::{DiagnosticMessageId, Session};
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
use rustc_span::{symbol, Span, Symbol, DUMMY_SP};
Expand Down Expand Up @@ -245,7 +245,6 @@ impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> {
}

pub fn explain_lint_level_source(
sess: &Session,
lint: &'static Lint,
level: Level,
src: LintLevelSource,
Expand All @@ -254,11 +253,7 @@ pub fn explain_lint_level_source(
let name = lint.name_lower();
match src {
LintLevelSource::Default => {
sess.diag_note_once(
err,
DiagnosticMessageId::from(lint),
&format!("`#[{}({})]` on by default", level.as_str(), name),
);
err.note_once(&format!("`#[{}({})]` on by default", level.as_str(), name));
}
LintLevelSource::CommandLine(lint_flag_val, orig_level) => {
let flag = match orig_level {
Expand All @@ -273,46 +268,29 @@ pub fn explain_lint_level_source(
};
let hyphen_case_lint_name = name.replace('_', "-");
if lint_flag_val.as_str() == name {
sess.diag_note_once(
err,
DiagnosticMessageId::from(lint),
&format!(
"requested on the command line with `{} {}`",
flag, hyphen_case_lint_name
),
);
err.note_once(&format!(
"requested on the command line with `{} {}`",
flag, hyphen_case_lint_name
));
} else {
let hyphen_case_flag_val = lint_flag_val.as_str().replace('_', "-");
sess.diag_note_once(
err,
DiagnosticMessageId::from(lint),
&format!(
"`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
),
);
err.note_once(&format!(
"`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val
));
}
}
LintLevelSource::Node(lint_attr_name, src, reason) => {
if let Some(rationale) = reason {
err.note(rationale.as_str());
}
sess.diag_span_note_once(
err,
DiagnosticMessageId::from(lint),
src,
"the lint level is defined here",
);
err.span_note_once(src, "the lint level is defined here");
if lint_attr_name.as_str() != name {
let level_str = level.as_str();
sess.diag_note_once(
err,
DiagnosticMessageId::from(lint),
&format!(
"`#[{}({})]` implied by `#[{}({})]`",
level_str, name, level_str, lint_attr_name
),
);
err.note_once(&format!(
"`#[{}({})]` implied by `#[{}({})]`",
level_str, name, level_str, lint_attr_name
));
}
}
}
Expand Down Expand Up @@ -412,7 +390,7 @@ pub fn struct_lint_level<'s, 'd>(
return;
}

explain_lint_level_source(sess, lint, level, src, &mut err);
explain_lint_level_source(lint, level, src, &mut err);

let name = lint.name_lower();
let is_force_warn = matches!(level, Level::ForceWarn);
Expand Down
35 changes: 10 additions & 25 deletions compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer};
use rustc_session::parse::feature_err_issue;
use rustc_session::{DiagnosticMessageId, Session};
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{MultiSpan, Span};
use rustc_span::Span;
use std::num::NonZeroU32;

#[derive(PartialEq, Clone, Copy, Debug)]
Expand Down Expand Up @@ -94,30 +94,15 @@ pub fn report_unstable(
None => format!("use of unstable library feature '{}'", &feature),
};

let msp: MultiSpan = span.into();
let sm = &sess.parse_sess.source_map();
let span_key = msp.primary_span().and_then(|sp: Span| {
if !sp.is_dummy() {
let file = sm.lookup_char_pos(sp.lo()).file;
if file.is_imported() { None } else { Some(span) }
} else {
None
}
});

let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
if fresh {
if is_soft {
soft_handler(SOFT_UNSTABLE, span, &msg)
} else {
let mut err =
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg);
if let Some((inner_types, ref msg, sugg, applicability)) = suggestion {
err.span_suggestion(inner_types, msg, sugg, applicability);
}
err.emit();
if is_soft {
soft_handler(SOFT_UNSTABLE, span, &msg)
} else {
let mut err =
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg);
if let Some((inner_types, ref msg, sugg, applicability)) = suggestion {
err.span_suggestion(inner_types, msg, sugg, applicability);
}
err.emit();
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_mir_transform/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root);
assert_eq!(level, Level::Allow);
lint::explain_lint_level_source(
tcx.sess,
UNSAFE_OP_IN_UNSAFE_FN,
Level::Allow,
source,
Expand Down
Loading

0 comments on commit 0b49d05

Please sign in to comment.