Rollup merge of #100776 - Rejyr:diagnostic-migration-rustc-lint, r=davidtwco
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)
This commit is contained in:
commit
389dda149c
6 changed files with 299 additions and 126 deletions
|
@ -393,3 +393,37 @@ lint_builtin_deref_nullptr = dereferencing a null pointer
|
||||||
.label = this code causes undefined behavior when executed
|
.label = this code causes undefined behavior when executed
|
||||||
|
|
||||||
lint_builtin_asm_labels = avoid using named labels in inline assembly
|
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}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
//! `late_lint_methods!` invocation in `lib.rs`.
|
//! `late_lint_methods!` invocation in `lib.rs`.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
errors::BuiltinEllpisisInclusiveRangePatterns,
|
||||||
types::{transparent_newtype_field, CItemKind},
|
types::{transparent_newtype_field, CItemKind},
|
||||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
|
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
|
||||||
};
|
};
|
||||||
|
@ -1760,18 +1761,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
||||||
None => format!("&(..={})", end),
|
None => format!("&(..={})", end),
|
||||||
};
|
};
|
||||||
if join.edition() >= Edition::Edition2021 {
|
if join.edition() >= Edition::Edition2021 {
|
||||||
let mut err = cx.sess().struct_span_err_with_code(
|
cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
|
||||||
pat.span,
|
span: pat.span,
|
||||||
msg,
|
suggestion: pat.span,
|
||||||
rustc_errors::error_code!(E0783),
|
|
||||||
);
|
|
||||||
err.span_suggestion(
|
|
||||||
pat.span,
|
|
||||||
suggestion,
|
|
||||||
replace,
|
replace,
|
||||||
Applicability::MachineApplicable,
|
});
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
} else {
|
} else {
|
||||||
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| {
|
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| {
|
||||||
lint.build(msg)
|
lint.build(msg)
|
||||||
|
@ -1787,18 +1781,11 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
|
||||||
} else {
|
} else {
|
||||||
let replace = "..=";
|
let replace = "..=";
|
||||||
if join.edition() >= Edition::Edition2021 {
|
if join.edition() >= Edition::Edition2021 {
|
||||||
let mut err = cx.sess().struct_span_err_with_code(
|
cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns {
|
||||||
pat.span,
|
span: pat.span,
|
||||||
msg,
|
suggestion: join,
|
||||||
rustc_errors::error_code!(E0783),
|
replace: replace.to_string(),
|
||||||
);
|
});
|
||||||
err.span_suggestion_short(
|
|
||||||
join,
|
|
||||||
suggestion,
|
|
||||||
replace,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
} else {
|
} else {
|
||||||
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| {
|
cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| {
|
||||||
lint.build(msg)
|
lint.build(msg)
|
||||||
|
|
|
@ -16,12 +16,16 @@
|
||||||
|
|
||||||
use self::TargetLint::*;
|
use self::TargetLint::*;
|
||||||
|
|
||||||
|
use crate::errors::{
|
||||||
|
CheckNameDeprecated, CheckNameUnknown, CheckNameUnknownTool, CheckNameWarning, RequestedLevel,
|
||||||
|
UnsupportedGroup,
|
||||||
|
};
|
||||||
use crate::levels::LintLevelsBuilder;
|
use crate::levels::LintLevelsBuilder;
|
||||||
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
|
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
|
||||||
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
|
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync;
|
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::{
|
use rustc_errors::{
|
||||||
Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
|
Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
|
||||||
};
|
};
|
||||||
|
@ -39,7 +43,7 @@ use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintI
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::lev_distance::find_best_match_for_name;
|
use rustc_span::lev_distance::find_best_match_for_name;
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
use rustc_span::{BytePos, Span};
|
||||||
use rustc_target::abi;
|
use rustc_target::abi;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
@ -326,68 +330,41 @@ impl LintStore {
|
||||||
) {
|
) {
|
||||||
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
|
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(_)) {
|
if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn(_)) {
|
||||||
struct_span_err!(
|
sess.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
|
||||||
sess,
|
|
||||||
DUMMY_SP,
|
|
||||||
E0602,
|
|
||||||
"`{}` lint group is not supported with ´--force-warn´",
|
|
||||||
crate::WARNINGS.name_lower()
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let db = match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
|
let lint_name = lint_name.to_string();
|
||||||
CheckLintNameResult::Ok(_) => None,
|
match self.check_lint_name(lint_name_only, tool_name, registered_tools) {
|
||||||
CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)),
|
CheckLintNameResult::Warning(msg, _) => {
|
||||||
|
sess.emit_warning(CheckNameWarning {
|
||||||
|
msg,
|
||||||
|
sub: RequestedLevel { level, lint_name },
|
||||||
|
});
|
||||||
|
}
|
||||||
CheckLintNameResult::NoLint(suggestion) => {
|
CheckLintNameResult::NoLint(suggestion) => {
|
||||||
let mut err =
|
sess.emit_err(CheckNameUnknown {
|
||||||
struct_span_err!(sess, DUMMY_SP, E0602, "unknown lint: `{}`", lint_name);
|
lint_name: lint_name.clone(),
|
||||||
|
suggestion,
|
||||||
if let Some(suggestion) = suggestion {
|
sub: RequestedLevel { level, lint_name },
|
||||||
err.help(&format!("did you mean: `{}`", suggestion));
|
});
|
||||||
}
|
}
|
||||||
|
CheckLintNameResult::Tool(result) => {
|
||||||
Some(err.forget_guarantee())
|
if let Err((Some(_), new_name)) = result {
|
||||||
|
sess.emit_warning(CheckNameDeprecated {
|
||||||
|
lint_name: lint_name.clone(),
|
||||||
|
new_name,
|
||||||
|
sub: RequestedLevel { level, lint_name },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
CheckLintNameResult::Tool(result) => match result {
|
}
|
||||||
Err((Some(_), new_name)) => Some(sess.struct_warn(&format!(
|
CheckLintNameResult::NoTool => {
|
||||||
"lint name `{}` is deprecated \
|
sess.emit_err(CheckNameUnknownTool {
|
||||||
and does not have an effect anymore. \
|
tool_name: tool_name.unwrap(),
|
||||||
Use: {}",
|
sub: RequestedLevel { level, lint_name },
|
||||||
lint_name, new_name
|
});
|
||||||
))),
|
}
|
||||||
_ => None,
|
_ => {}
|
||||||
},
|
|
||||||
CheckLintNameResult::NoTool => Some(
|
|
||||||
struct_span_err!(
|
|
||||||
sess,
|
|
||||||
DUMMY_SP,
|
|
||||||
E0602,
|
|
||||||
"unknown lint tool: `{}`",
|
|
||||||
tool_name.unwrap()
|
|
||||||
)
|
|
||||||
.forget_guarantee(),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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.
|
/// True if this symbol represents a lint group name.
|
||||||
|
|
162
compiler/rustc_lint/src/errors.rs
Normal file
162
compiler/rustc_lint/src/errors.rs
Normal file
|
@ -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,
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ use crate::late::unerased_lint_store;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan};
|
use rustc_errors::{Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::{intravisit, HirId};
|
use rustc_hir::{intravisit, HirId};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
|
@ -23,6 +23,11 @@ use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::errors::{
|
||||||
|
MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub,
|
||||||
|
UnknownToolInScopedLint,
|
||||||
|
};
|
||||||
|
|
||||||
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
|
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
|
||||||
let store = unerased_lint_store(tcx);
|
let store = unerased_lint_store(tcx);
|
||||||
let levels =
|
let levels =
|
||||||
|
@ -186,16 +191,26 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !fcw_warning {
|
if !fcw_warning {
|
||||||
let mut diag_builder = struct_span_err!(
|
self.sess.emit_err(OverruledAttribute {
|
||||||
self.sess,
|
span: src.span(),
|
||||||
src.span(),
|
overruled: src.span(),
|
||||||
E0453,
|
lint_level: level.as_str().to_string(),
|
||||||
"{}({}) incompatible with previous forbid",
|
lint_source: src.name(),
|
||||||
level.as_str(),
|
sub: match old_src {
|
||||||
src.name(),
|
LintLevelSource::Default => {
|
||||||
);
|
OverruledAttributeSub::DefaultSource { id: id.to_string() }
|
||||||
decorate_diag(&mut diag_builder);
|
}
|
||||||
diag_builder.emit();
|
LintLevelSource::Node(_, forbid_source_span, reason) => {
|
||||||
|
OverruledAttributeSub::NodeSource {
|
||||||
|
span: forbid_source_span,
|
||||||
|
reason,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LintLevelSource::CommandLine(_, _) => {
|
||||||
|
OverruledAttributeSub::CommandLineSource
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
self.struct_lint(
|
self.struct_lint(
|
||||||
FORBIDDEN_LINT_GROUPS,
|
FORBIDDEN_LINT_GROUPS,
|
||||||
|
@ -266,7 +281,6 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev });
|
self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev });
|
||||||
|
|
||||||
let sess = self.sess;
|
let sess = self.sess;
|
||||||
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
|
|
||||||
for (attr_index, attr) in attrs.iter().enumerate() {
|
for (attr_index, attr) in attrs.iter().enumerate() {
|
||||||
if attr.has_name(sym::automatically_derived) {
|
if attr.has_name(sym::automatically_derived) {
|
||||||
self.current_specs_mut().insert(
|
self.current_specs_mut().insert(
|
||||||
|
@ -317,20 +331,27 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
}
|
}
|
||||||
reason = Some(rationale);
|
reason = Some(rationale);
|
||||||
} else {
|
} else {
|
||||||
bad_attr(name_value.span)
|
sess.emit_err(MalformedAttribute {
|
||||||
.span_label(name_value.span, "reason must be a string literal")
|
span: name_value.span,
|
||||||
.emit();
|
sub: MalformedAttributeSub::ReasonMustBeStringLiteral(
|
||||||
|
name_value.span,
|
||||||
|
),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// found reason, reslice meta list to exclude it
|
// found reason, reslice meta list to exclude it
|
||||||
metas.pop().unwrap();
|
metas.pop().unwrap();
|
||||||
} else {
|
} else {
|
||||||
bad_attr(item.span)
|
sess.emit_err(MalformedAttribute {
|
||||||
.span_label(item.span, "bad attribute argument")
|
span: item.span,
|
||||||
.emit();
|
sub: MalformedAttributeSub::BadAttributeArgument(item.span),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::MetaItemKind::List(_) => {
|
ast::MetaItemKind::List(_) => {
|
||||||
bad_attr(item.span).span_label(item.span, "bad attribute argument").emit();
|
sess.emit_err(MalformedAttribute {
|
||||||
|
span: item.span,
|
||||||
|
sub: MalformedAttributeSub::BadAttributeArgument(item.span),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,20 +369,21 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
let meta_item = match li {
|
let meta_item = match li {
|
||||||
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
|
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
|
||||||
_ => {
|
_ => {
|
||||||
let mut err = bad_attr(sp);
|
|
||||||
let mut add_label = true;
|
|
||||||
if let Some(item) = li.meta_item() {
|
if let Some(item) = li.meta_item() {
|
||||||
if let ast::MetaItemKind::NameValue(_) = item.kind {
|
if let ast::MetaItemKind::NameValue(_) = item.kind {
|
||||||
if item.path == sym::reason {
|
if item.path == sym::reason {
|
||||||
err.span_label(sp, "reason in lint attribute must come last");
|
sess.emit_err(MalformedAttribute {
|
||||||
add_label = false;
|
span: sp,
|
||||||
|
sub: MalformedAttributeSub::ReasonMustComeLast(sp),
|
||||||
|
});
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if add_label {
|
sess.emit_err(MalformedAttribute {
|
||||||
err.span_label(sp, "bad attribute argument");
|
span: sp,
|
||||||
}
|
sub: MalformedAttributeSub::BadAttributeArgument(sp),
|
||||||
err.emit();
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -485,22 +507,12 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
&CheckLintNameResult::NoTool => {
|
&CheckLintNameResult::NoTool => {
|
||||||
let mut err = struct_span_err!(
|
sess.emit_err(UnknownToolInScopedLint {
|
||||||
sess,
|
span: tool_ident.map(|ident| ident.span),
|
||||||
tool_ident.map_or(DUMMY_SP, |ident| ident.span),
|
tool_name: tool_name.unwrap(),
|
||||||
E0710,
|
lint_name: pprust::path_to_string(&meta_item.path),
|
||||||
"unknown tool name `{}` found in scoped lint: `{}::{}`",
|
is_nightly_build: sess.is_nightly_build().then_some(()),
|
||||||
tool_name.unwrap(),
|
});
|
||||||
tool_name.unwrap(),
|
|
||||||
pprust::path_to_string(&meta_item.path),
|
|
||||||
);
|
|
||||||
if sess.is_nightly_build() {
|
|
||||||
err.help(&format!(
|
|
||||||
"add `#![register_tool({})]` to the crate root",
|
|
||||||
tool_name.unwrap()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
err.emit();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub mod builtin;
|
||||||
mod context;
|
mod context;
|
||||||
mod early;
|
mod early;
|
||||||
mod enum_intrinsics_non_enums;
|
mod enum_intrinsics_non_enums;
|
||||||
|
mod errors;
|
||||||
mod expect;
|
mod expect;
|
||||||
pub mod hidden_unicode_codepoints;
|
pub mod hidden_unicode_codepoints;
|
||||||
mod internal;
|
mod internal;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue