mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 09:53:26 +00:00
migrate: unused.rs
This commit is contained in:
parent
d44ccaa56f
commit
e5ae9d019c
@ -1,7 +1,11 @@
|
|||||||
use rustc_errors::{fluent, AddSubdiagnostic, DecorateLint, EmissionGuarantee};
|
use rustc_errors::{fluent, AddSubdiagnostic, Applicability, DecorateLint, EmissionGuarantee};
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::{LintDiagnostic, SessionSubdiagnostic};
|
use rustc_macros::{LintDiagnostic, SessionSubdiagnostic};
|
||||||
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
|
use crate::LateContext;
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(lint_range_endpoint_out_of_range)]
|
#[diag(lint_range_endpoint_out_of_range)]
|
||||||
pub struct RangeEndpointOutOfRange<'a> {
|
pub struct RangeEndpointOutOfRange<'a> {
|
||||||
@ -146,3 +150,130 @@ pub struct InvalidAtomicOrderingDiag {
|
|||||||
#[label]
|
#[label]
|
||||||
pub fail_order_arg_span: Span,
|
pub fail_order_arg_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_op)]
|
||||||
|
pub struct UnusedOp<'a> {
|
||||||
|
pub op: &'a str,
|
||||||
|
#[label]
|
||||||
|
pub label: Span,
|
||||||
|
#[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
|
||||||
|
pub suggestion: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_result)]
|
||||||
|
pub struct UnusedResult<'a> {
|
||||||
|
pub ty: Ty<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(davidtwco): this isn't properly translatable becauses of the
|
||||||
|
// pre/post strings
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_closure)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnusedClosure<'a> {
|
||||||
|
pub count: usize,
|
||||||
|
pub pre: &'a str,
|
||||||
|
pub post: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(davidtwco): this isn't properly translatable becauses of the
|
||||||
|
// pre/post strings
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_generator)]
|
||||||
|
#[note]
|
||||||
|
pub struct UnusedGenerator<'a> {
|
||||||
|
pub count: usize,
|
||||||
|
pub pre: &'a str,
|
||||||
|
pub post: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
|
||||||
|
// strings
|
||||||
|
pub struct UnusedDef<'a, 'b> {
|
||||||
|
pub pre: &'a str,
|
||||||
|
pub post: &'a str,
|
||||||
|
pub cx: &'a LateContext<'b>,
|
||||||
|
pub def_id: DefId,
|
||||||
|
pub note: Option<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: refactor with `Option<String>` in macro
|
||||||
|
impl<'a, 'b, G: EmissionGuarantee> DecorateLint<'_, G> for UnusedDef<'a, 'b> {
|
||||||
|
fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
|
||||||
|
let mut diag = diag.build(fluent::lint_unused_def);
|
||||||
|
diag.set_arg("pre", self.pre);
|
||||||
|
diag.set_arg("post", self.post);
|
||||||
|
diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
|
||||||
|
// check for #[must_use = "..."]
|
||||||
|
if let Some(note) = self.note {
|
||||||
|
diag.note(note.as_str());
|
||||||
|
}
|
||||||
|
diag.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_path_statement_drop)]
|
||||||
|
pub struct PathStatementDrop {
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub sub: PathStatementDropSub,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionSubdiagnostic)]
|
||||||
|
pub enum PathStatementDropSub {
|
||||||
|
#[suggestion(
|
||||||
|
suggestion,
|
||||||
|
code = "drop({snippet});",
|
||||||
|
applicability = "machine-applicable"
|
||||||
|
)]
|
||||||
|
Suggestion {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
snippet: String,
|
||||||
|
},
|
||||||
|
#[help(help)]
|
||||||
|
Help {
|
||||||
|
#[primary_span]
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_path_statement_no_effect)]
|
||||||
|
pub struct PathStatementNoEffect;
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_delim)]
|
||||||
|
pub struct UnusedDelim<'a> {
|
||||||
|
pub delim: &'static str,
|
||||||
|
pub item: &'a str,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub suggestion: Option<UnusedDelimSuggestion>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[multipart_suggestion(suggestion, applicability = "machine-applicable")]
|
||||||
|
pub struct UnusedDelimSuggestion {
|
||||||
|
#[suggestion_part(code = "{start_replace}")]
|
||||||
|
pub start_span: Span,
|
||||||
|
pub start_replace: &'static str,
|
||||||
|
#[suggestion_part(code = "{end_replace}")]
|
||||||
|
pub end_span: Span,
|
||||||
|
pub end_replace: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_import_braces)]
|
||||||
|
pub struct UnusedImportBracesDiag {
|
||||||
|
pub node: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_allocation)]
|
||||||
|
pub struct UnusedAllocationDiag;
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_unused_allocation_mut)]
|
||||||
|
pub struct UnusedAllocationMutDiag;
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
|
use crate::lints::{
|
||||||
|
PathStatementDrop, PathStatementDropSub, PathStatementNoEffect, UnusedAllocationDiag,
|
||||||
|
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDelim, UnusedDelimSuggestion,
|
||||||
|
UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
|
||||||
|
};
|
||||||
use crate::Lint;
|
use crate::Lint;
|
||||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::util::{classify, parser};
|
use rustc_ast::util::{classify, parser};
|
||||||
use rustc_ast::{ExprKind, StmtKind};
|
use rustc_ast::{ExprKind, StmtKind};
|
||||||
use rustc_errors::{fluent, pluralize, Applicability, MultiSpan};
|
use rustc_errors::{pluralize, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
@ -163,23 +170,20 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
let mut op_warned = false;
|
let mut op_warned = false;
|
||||||
|
|
||||||
if let Some(must_use_op) = must_use_op {
|
if let Some(must_use_op) = must_use_op {
|
||||||
cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint_unused_op, |lint| {
|
cx.emit_spanned_lint(
|
||||||
lint.set_arg("op", must_use_op)
|
UNUSED_MUST_USE,
|
||||||
.span_label(expr.span, fluent::label)
|
expr.span,
|
||||||
.span_suggestion_verbose(
|
UnusedOp {
|
||||||
expr.span.shrink_to_lo(),
|
op: must_use_op,
|
||||||
fluent::suggestion,
|
label: expr.span,
|
||||||
"let _ = ",
|
suggestion: expr.span.shrink_to_lo(),
|
||||||
Applicability::MachineApplicable,
|
},
|
||||||
)
|
);
|
||||||
});
|
|
||||||
op_warned = true;
|
op_warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) {
|
if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) {
|
||||||
cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint_unused_result, |lint| {
|
cx.emit_spanned_lint(UNUSED_RESULTS, s.span, UnusedResult { ty });
|
||||||
lint.set_arg("ty", ty)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||||
@ -402,47 +406,31 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
MustUsePath::Closure(span) => {
|
MustUsePath::Closure(span) => {
|
||||||
cx.struct_span_lint(
|
cx.emit_spanned_lint(
|
||||||
UNUSED_MUST_USE,
|
UNUSED_MUST_USE,
|
||||||
*span,
|
*span,
|
||||||
fluent::lint_unused_closure,
|
UnusedClosure { count: plural_len, pre: descr_pre, post: descr_post },
|
||||||
|lint| {
|
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
|
||||||
// pre/post strings
|
|
||||||
lint.set_arg("count", plural_len)
|
|
||||||
.set_arg("pre", descr_pre)
|
|
||||||
.set_arg("post", descr_post)
|
|
||||||
.note(fluent::note)
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
MustUsePath::Generator(span) => {
|
MustUsePath::Generator(span) => {
|
||||||
cx.struct_span_lint(
|
cx.emit_spanned_lint(
|
||||||
UNUSED_MUST_USE,
|
UNUSED_MUST_USE,
|
||||||
*span,
|
*span,
|
||||||
fluent::lint_unused_generator,
|
UnusedGenerator { count: plural_len, pre: descr_pre, post: descr_post },
|
||||||
|lint| {
|
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the
|
|
||||||
// pre/post strings
|
|
||||||
lint.set_arg("count", plural_len)
|
|
||||||
.set_arg("pre", descr_pre)
|
|
||||||
.set_arg("post", descr_post)
|
|
||||||
.note(fluent::note)
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
MustUsePath::Def(span, def_id, reason) => {
|
MustUsePath::Def(span, def_id, reason) => {
|
||||||
cx.struct_span_lint(UNUSED_MUST_USE, *span, fluent::lint_unused_def, |lint| {
|
cx.emit_spanned_lint(
|
||||||
// FIXME(davidtwco): this isn't properly translatable because of the pre/post
|
UNUSED_MUST_USE,
|
||||||
// strings
|
*span,
|
||||||
lint.set_arg("pre", descr_pre);
|
UnusedDef {
|
||||||
lint.set_arg("post", descr_post);
|
pre: descr_pre,
|
||||||
lint.set_arg("def", cx.tcx.def_path_str(*def_id));
|
post: descr_post,
|
||||||
if let Some(note) = reason {
|
cx,
|
||||||
lint.note(note.as_str());
|
def_id: *def_id,
|
||||||
}
|
note: *reason,
|
||||||
lint
|
},
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,31 +466,15 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
|
|||||||
if let hir::ExprKind::Path(_) = expr.kind {
|
if let hir::ExprKind::Path(_) = expr.kind {
|
||||||
let ty = cx.typeck_results().expr_ty(expr);
|
let ty = cx.typeck_results().expr_ty(expr);
|
||||||
if ty.needs_drop(cx.tcx, cx.param_env) {
|
if ty.needs_drop(cx.tcx, cx.param_env) {
|
||||||
cx.struct_span_lint(
|
let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span)
|
||||||
PATH_STATEMENTS,
|
{
|
||||||
s.span,
|
PathStatementDropSub::Suggestion { span: s.span, snippet }
|
||||||
fluent::lint_path_statement_drop,
|
} else {
|
||||||
|lint| {
|
PathStatementDropSub::Help { span: s.span }
|
||||||
if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
|
};
|
||||||
lint.span_suggestion(
|
cx.emit_spanned_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub })
|
||||||
s.span,
|
|
||||||
fluent::suggestion,
|
|
||||||
format!("drop({});", snippet),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
lint.span_help(s.span, fluent::suggestion);
|
|
||||||
}
|
|
||||||
lint
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
cx.struct_span_lint(
|
cx.emit_spanned_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect);
|
||||||
PATH_STATEMENTS,
|
|
||||||
s.span,
|
|
||||||
fluent::lint_path_statement_no_effect,
|
|
||||||
|lint| lint,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,36 +667,35 @@ trait UnusedDelimLint {
|
|||||||
} else {
|
} else {
|
||||||
MultiSpan::from(value_span)
|
MultiSpan::from(value_span)
|
||||||
};
|
};
|
||||||
cx.struct_span_lint(self.lint(), primary_span, fluent::lint_unused_delim, |lint| {
|
let suggestion = spans.map(|(lo, hi)| {
|
||||||
lint.set_arg("delim", Self::DELIM_STR);
|
let sm = cx.sess().source_map();
|
||||||
lint.set_arg("item", msg);
|
let lo_replace =
|
||||||
if let Some((lo, hi)) = spans {
|
|
||||||
let sm = cx.sess().source_map();
|
|
||||||
let lo_replace =
|
|
||||||
if keep_space.0 &&
|
if keep_space.0 &&
|
||||||
let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
|
let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
|
||||||
" ".to_string()
|
" "
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
let hi_replace =
|
let hi_replace =
|
||||||
if keep_space.1 &&
|
if keep_space.1 &&
|
||||||
let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') {
|
let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') {
|
||||||
" ".to_string()
|
" "
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
""
|
||||||
};
|
};
|
||||||
|
UnusedDelimSuggestion {
|
||||||
let replacement = vec![(lo, lo_replace), (hi, hi_replace)];
|
start_span: lo,
|
||||||
lint.multipart_suggestion(
|
start_replace: lo_replace,
|
||||||
fluent::suggestion,
|
end_span: hi,
|
||||||
replacement,
|
end_replace: hi_replace,
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
lint
|
|
||||||
});
|
});
|
||||||
|
cx.emit_spanned_lint(
|
||||||
|
self.lint(),
|
||||||
|
primary_span,
|
||||||
|
UnusedDelim { delim: Self::DELIM_STR, item: msg, suggestion },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||||
@ -1297,11 +1268,10 @@ impl UnusedImportBraces {
|
|||||||
ast::UseTreeKind::Nested(_) => return,
|
ast::UseTreeKind::Nested(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.struct_span_lint(
|
cx.emit_spanned_lint(
|
||||||
UNUSED_IMPORT_BRACES,
|
UNUSED_IMPORT_BRACES,
|
||||||
item.span,
|
item.span,
|
||||||
fluent::lint_unused_import_braces,
|
UnusedImportBracesDiag { node: node_name },
|
||||||
|lint| lint.set_arg("node", node_name),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1351,17 +1321,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
|
|||||||
|
|
||||||
for adj in cx.typeck_results().expr_adjustments(e) {
|
for adj in cx.typeck_results().expr_adjustments(e) {
|
||||||
if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
|
if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
|
||||||
cx.struct_span_lint(
|
match m {
|
||||||
UNUSED_ALLOCATION,
|
adjustment::AutoBorrowMutability::Not => {
|
||||||
e.span,
|
cx.emit_spanned_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag);
|
||||||
match m {
|
}
|
||||||
adjustment::AutoBorrowMutability::Not => fluent::lint_unused_allocation,
|
adjustment::AutoBorrowMutability::Mut { .. } => {
|
||||||
adjustment::AutoBorrowMutability::Mut { .. } => {
|
cx.emit_spanned_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationMutDiag);
|
||||||
fluent::lint_unused_allocation_mut
|
}
|
||||||
}
|
};
|
||||||
},
|
|
||||||
|lint| lint,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user