Skip to content

Commit

Permalink
Rollup merge of #100776 - Rejyr:diagnostic-migration-rustc-lint, r=da…
Browse files Browse the repository at this point in the history
…vidtwco

Migrate `rustc_lint` errors to `SessionDiagnostic`

Draft PR for migrating `rustc_lint` to `SessionDiagnostic`, as part of the [recent blog post](https://blog.rust-lang.org/inside-rust/2022/08/16/diagnostic-effort.html)
  • Loading branch information
compiler-errors committed Aug 26, 2022
2 parents 93b2acd + 1693993 commit 389dda1
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 124 deletions.
34 changes: 34 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/lint.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,37 @@ lint_builtin_deref_nullptr = dereferencing a null pointer
.label = this code causes undefined behavior when executed
lint_builtin_asm_labels = avoid using named labels in inline assembly
lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid
.label = overruled by previous forbid
lint_default_source = `forbid` lint level is the default for {$id}
lint_node_source = `forbid` level set here
.note = {$reason}
lint_command_line_source = `forbid` lint level was set on command line
lint_malformed_attribute = malformed lint attribute input
lint_bad_attribute_argument = bad attribute argument
lint_reason_must_be_string_literal = reason must be a string literal
lint_reason_must_come_last = reason in lint attribute must come last
lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}`
.help = add `#![register_tool({$tool_name})]` to the crate root
lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
lint_check_name_unknown = unknown lint: `{$lint_name}`
.help = did you mean: `{$suggestion}`
lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}`
lint_check_name_warning = {$msg}
lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name}
33 changes: 10 additions & 23 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//! `late_lint_methods!` invocation in `lib.rs`.

use crate::{
errors::BuiltinEllpisisInclusiveRangePatterns,
types::{transparent_newtype_field, CItemKind},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
};
Expand Down Expand Up @@ -1760,18 +1761,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
None => format!("&(..={})", end),
};
if join.edition() >= Edition::Edition2021 {
let mut err = cx.sess().struct_span_err_with_code(
pat.span,
msg,
rustc_errors::error_code!(E0783),
);
err.span_suggestion(
pat.span,
suggestion,
cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
span: pat.span,
suggestion: pat.span,
replace,
Applicability::MachineApplicable,
)
.emit();
});
} else {
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| {
lint.build(msg)
Expand All @@ -1787,18 +1781,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
} else {
let replace = "..=";
if join.edition() >= Edition::Edition2021 {
let mut err = cx.sess().struct_span_err_with_code(
pat.span,
msg,
rustc_errors::error_code!(E0783),
);
err.span_suggestion_short(
join,
suggestion,
replace,
Applicability::MachineApplicable,
)
.emit();
cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
span: pat.span,
suggestion: join,
replace: replace.to_string(),
});
} else {
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| {
lint.build(msg)
Expand Down
93 changes: 35 additions & 58 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

use self::TargetLint::*;

use crate::errors::{
CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel,
UnsupportedGroup,
};
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err};
use rustc_errors::add_elided_lifetime_in_path_suggestion;
use rustc_errors::{
Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
};
Expand All @@ -39,7 +43,7 @@ use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintI
use rustc_session::Session;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{BytePos, Span, DUMMY_SP};
use rustc_span::{BytePos, Span};
use rustc_target::abi;
use tracing::debug;

Expand Down Expand Up @@ -326,68 +330,41 @@ impl LintStore {
) {
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn(_)) {
struct_span_err!(
sess,
DUMMY_SP,
E0602,
"`{}` lint group is not supported with ´--force-warn´",
crate::WARNINGS.name_lower()
)
.emit();
sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
return;
}
let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
CheckLintNameResult::Ok(_) => None,
CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)),
let lint_name = lint_name.to_string();
match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
CheckLintNameResult::Warning(msg, _) => {
sess.emit_warning(CheckNameWarning {
msg,
sub: RequestedLevel { level, lint_name },
});
}
CheckLintNameResult::NoLint(suggestion) => {
let mut err =
struct_span_err!(sess, DUMMY_SP, E0602, "unknown lint: `{}`", lint_name);

if let Some(suggestion) = suggestion {
err.help(&format!("did you mean: `{}`", suggestion));
sess.emit_err(CheckNameUnknown {
lint_name: lint_name.clone(),
suggestion,
sub: RequestedLevel { level, lint_name },
});
}
CheckLintNameResult::Tool(result) => {
if let Err((Some(_), new_name)) = result {
sess.emit_warning(CheckNameDeprecated {
lint_name: lint_name.clone(),
new_name,
sub: RequestedLevel { level, lint_name },
});
}

Some(err.forget_guarantee())
}
CheckLintNameResult::Tool(result) => match result {
Err((Some(_), new_name)) => Some(sess.struct_warn(&format!(
"lint name `{}` is deprecated \
and does not have an effect anymore. \
Use: {}",
lint_name, new_name
))),
_ => None,
},
CheckLintNameResult::NoTool => Some(
struct_span_err!(
sess,
DUMMY_SP,
E0602,
"unknown lint tool: `{}`",
tool_name.unwrap()
)
.forget_guarantee(),
),
CheckLintNameResult::NoTool => {
sess.emit_err(CheckNameUnknownTool {
tool_name: tool_name.unwrap(),
sub: RequestedLevel { level, lint_name },
});
}
_ => {}
};

if let Some(mut db) = db {
let msg = format!(
"requested on the command line with `{} {}`",
match level {
Level::Allow => "-A",
Level::Warn => "-W",
Level::ForceWarn(_) => "--force-warn",
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Expect(_) => {
unreachable!("lints with the level of `expect` should not run this code");
}
},
lint_name
);
db.note(&msg);
db.emit();
}
}

/// True if this symbol represents a lint group name.
Expand Down
162 changes: 162 additions & 0 deletions compiler/rustc_lint/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use rustc_errors::{fluent, AddSubdiagnostic, ErrorGuaranteed};
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
use rustc_session::{lint::Level, parse::ParseSess, SessionDiagnostic};
use rustc_span::{Span, Symbol};

#[derive(SessionDiagnostic)]
#[diag(lint::overruled_attribute, code = "E0453")]
pub struct OverruledAttribute {
#[primary_span]
pub span: Span,
#[label]
pub overruled: Span,
pub lint_level: String,
pub lint_source: Symbol,
#[subdiagnostic]
pub sub: OverruledAttributeSub,
}
//
pub enum OverruledAttributeSub {
DefaultSource { id: String },
NodeSource { span: Span, reason: Option<Symbol> },
CommandLineSource,
}

impl AddSubdiagnostic for OverruledAttributeSub {
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
match self {
OverruledAttributeSub::DefaultSource { id } => {
diag.note(fluent::lint::default_source);
diag.set_arg("id", id);
}
OverruledAttributeSub::NodeSource { span, reason } => {
diag.span_label(span, fluent::lint::node_source);
if let Some(rationale) = reason {
diag.note(rationale.as_str());
}
}
OverruledAttributeSub::CommandLineSource => {
diag.note(fluent::lint::command_line_source);
}
}
}
}

#[derive(SessionDiagnostic)]
#[diag(lint::malformed_attribute, code = "E0452")]
pub struct MalformedAttribute {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub sub: MalformedAttributeSub,
}

#[derive(SessionSubdiagnostic)]
pub enum MalformedAttributeSub {
#[label(lint::bad_attribute_argument)]
BadAttributeArgument(#[primary_span] Span),
#[label(lint::reason_must_be_string_literal)]
ReasonMustBeStringLiteral(#[primary_span] Span),
#[label(lint::reason_must_come_last)]
ReasonMustComeLast(#[primary_span] Span),
}

#[derive(SessionDiagnostic)]
#[diag(lint::unknown_tool_in_scoped_lint, code = "E0710")]
pub struct UnknownToolInScopedLint {
#[primary_span]
pub span: Option<Span>,
pub tool_name: Symbol,
pub lint_name: String,
#[help]
pub is_nightly_build: Option<()>,
}

#[derive(SessionDiagnostic)]
#[diag(lint::builtin_ellipsis_inclusive_range_patterns, code = "E0783")]
pub struct BuiltinEllpisisInclusiveRangePatterns {
#[primary_span]
pub span: Span,
#[suggestion_short(code = "{replace}", applicability = "machine-applicable")]
pub suggestion: Span,
pub replace: String,
}

pub struct RequestedLevel {
pub level: Level,
pub lint_name: String,
}

impl AddSubdiagnostic for RequestedLevel {
fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
diag.note(fluent::lint::requested_level);
diag.set_arg(
"level",
match self.level {
Level::Allow => "-A",
Level::Warn => "-W",
Level::ForceWarn(_) => "--force-warn",
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Expect(_) => {
unreachable!("lints with the level of `expect` should not run this code");
}
},
);
diag.set_arg("lint_name", self.lint_name);
}
}

#[derive(SessionDiagnostic)]
#[diag(lint::unsupported_group, code = "E0602")]
pub struct UnsupportedGroup {
pub lint_group: String,
}

pub struct CheckNameUnknown {
pub lint_name: String,
pub suggestion: Option<Symbol>,
pub sub: RequestedLevel,
}

impl SessionDiagnostic<'_> for CheckNameUnknown {
fn into_diagnostic(
self,
sess: &ParseSess,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = sess.struct_err(fluent::lint::check_name_unknown);
diag.code(rustc_errors::error_code!(E0602));
if let Some(suggestion) = self.suggestion {
diag.help(fluent::lint::help);
diag.set_arg("suggestion", suggestion);
}
diag.set_arg("lint_name", self.lint_name);
diag.subdiagnostic(self.sub);
diag
}
}

#[derive(SessionDiagnostic)]
#[diag(lint::check_name_unknown_tool, code = "E0602")]
pub struct CheckNameUnknownTool {
pub tool_name: Symbol,
#[subdiagnostic]
pub sub: RequestedLevel,
}

#[derive(SessionDiagnostic)]
#[diag(lint::check_name_warning)]
pub struct CheckNameWarning {
pub msg: String,
#[subdiagnostic]
pub sub: RequestedLevel,
}

#[derive(SessionDiagnostic)]
#[diag(lint::check_name_deprecated)]
pub struct CheckNameDeprecated {
pub lint_name: String,
pub new_name: String,
#[subdiagnostic]
pub sub: RequestedLevel,
}
Loading

0 comments on commit 389dda1

Please sign in to comment.