Skip to content

Commit 3740da2

Browse files
committed
Fix bugs and improve documentation
Some bugs and some documentation is unrelated to the Applicability change, but these bugs were serious and the documentation was kind of required to understand what's going on.
1 parent 9096269 commit 3740da2

File tree

5 files changed

+56
-18
lines changed

5 files changed

+56
-18
lines changed

clippy_lints/src/else_if_without_else.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
1313
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext};
1414
use crate::rustc::{declare_tool_lint, lint_array};
15-
use crate::rustc_errors::Applicability;
1615
use crate::syntax::ast::*;
1716

18-
use crate::utils::span_lint_and_sugg;
17+
use crate::utils::span_help_and_lint;
1918

2019
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
2120
/// but without a final `else` branch.
@@ -67,14 +66,12 @@ impl EarlyLintPass for ElseIfWithoutElse {
6766

6867
while let ExprKind::If(_, _, Some(ref els)) = item.node {
6968
if let ExprKind::If(_, _, None) = els.node {
70-
span_lint_and_sugg(
69+
span_help_and_lint(
7170
cx,
7271
ELSE_IF_WITHOUT_ELSE,
7372
els.span,
7473
"if expression with an `else if`, but without a final `else`",
7574
"add an `else` block here",
76-
String::new(),
77-
Applicability::Unspecified,
7875
);
7976
}
8077

clippy_lints/src/methods/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,10 +2046,10 @@ fn lint_chars_next_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprIn
20462046

20472047
/// Checks for the `CHARS_LAST_CMP` lint.
20482048
fn lint_chars_last_cmp<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, info: &BinaryExprInfo<'_>) -> bool {
2049-
if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_NEXT_CMP, "ends_with") {
2049+
if lint_chars_cmp(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
20502050
true
20512051
} else {
2052-
lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_NEXT_CMP, "ends_with")
2052+
lint_chars_cmp(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with")
20532053
}
20542054
}
20552055

clippy_lints/src/utils/mod.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -384,24 +384,25 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str)
384384
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
385385
}
386386

387+
/// Same as `snippet`, but it adapts the applicability level by following rules:
388+
///
389+
/// - Applicability level `Unspecified` will never be changed.
390+
/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.
391+
/// - If the default value is used and the applicability level is `MachineApplicable`, change it to
392+
/// `HasPlaceholders`
387393
pub fn snippet_with_applicability<'a, 'b, T: LintContext<'b>>(
388394
cx: &T,
389395
span: Span,
390396
default: &'a str,
391397
applicability: &mut Applicability,
392398
) -> Cow<'a, str> {
399+
if *applicability != Applicability::Unspecified && in_macro(span) {
400+
*applicability = Applicability::MaybeIncorrect;
401+
}
393402
snippet_opt(cx, span).map_or_else(
394403
|| {
395-
// If the applicability is already `HasPlaceholders` or `MaybeIncorrect` don't change it.
396-
// Also `Unspecified` shouldn't be changed
397-
// Only if the applicability level is originally `MachineApplicable` and the default value
398-
// has to be used change it to `HasPlaceholders`
399404
if *applicability == Applicability::MachineApplicable {
400-
if in_macro(span) {
401-
*applicability = Applicability::MaybeIncorrect;
402-
} else {
403-
*applicability = Applicability::HasPlaceholders;
404-
}
405+
*applicability = Applicability::HasPlaceholders;
405406
}
406407
Cow::Borrowed(default)
407408
},
@@ -435,6 +436,18 @@ pub fn snippet_block<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'
435436
trim_multiline(snip, true)
436437
}
437438

439+
/// Same as `snippet_block`, but adapts the applicability level by the rules of
440+
/// `snippet_with_applicabiliy`.
441+
pub fn snippet_block_with_applicability<'a, 'b, T: LintContext<'b>>(
442+
cx: &T,
443+
span: Span,
444+
default: &'a str,
445+
applicability: &mut Applicability,
446+
) -> Cow<'a, str> {
447+
let snip = snippet_with_applicability(cx, span, default, applicability);
448+
trim_multiline(snip, true)
449+
}
450+
438451
/// Returns a new Span that covers the full last line of the given Span
439452
pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span {
440453
let source_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();

clippy_lints/src/utils/sugg.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::syntax::parse::token;
2424
use crate::syntax::print::pprust::token_to_string;
2525
use crate::syntax::util::parser::AssocOp;
2626
use crate::syntax::ast;
27-
use crate::utils::{higher, snippet, snippet_opt};
27+
use crate::utils::{higher, in_macro, snippet, snippet_opt};
2828
use crate::syntax_pos::{BytePos, Pos};
2929
use crate::rustc_errors::Applicability;
3030

@@ -96,7 +96,21 @@ impl<'a> Sugg<'a> {
9696
Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default)))
9797
}
9898

99-
pub fn hir_with_applicability(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str, applicability: &mut Applicability) -> Self {
99+
/// Same as `hir`, but it adapts the applicability level by following rules:
100+
///
101+
/// - Applicability level `Unspecified` will never be changed.
102+
/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.
103+
/// - If the default value is used and the applicability level is `MachineApplicable`, change it to
104+
/// `HasPlaceholders`
105+
pub fn hir_with_applicability(
106+
cx: &LateContext<'_, '_>,
107+
expr: &hir::Expr,
108+
default: &'a str,
109+
applicability: &mut Applicability,
110+
) -> Self {
111+
if *applicability != Applicability::Unspecified && in_macro(expr.span) {
112+
*applicability = Applicability::MaybeIncorrect;
113+
}
100114
Self::hir_opt(cx, expr).unwrap_or_else(|| {
101115
if *applicability == Applicability::MachineApplicable {
102116
*applicability = Applicability::HasPlaceholders;

clippy_lints/src/write.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ impl EarlyLintPass for Pass {
258258
}
259259
}
260260

261+
/// Checks the arguments of `print[ln]!` and `write[ln]!` calls. It will return a tuple of two
262+
/// options. The first part of the tuple is format_str of the macros. The secund part of the tuple
263+
/// is in the `write[ln]!` case the expression the format_str should be written to.
264+
///
265+
/// Example:
266+
///
267+
/// Calling this function on
268+
/// ```rust,ignore
269+
/// writeln!(buf, "string to write: {}", something)
270+
/// ```
271+
/// will return
272+
/// ```rust,ignore
273+
/// (Some("string to write: {}"), Some(buf))
274+
/// ```
261275
fn check_tts<'a>(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> (Option<String>, Option<Expr>) {
262276
use crate::fmt_macros::*;
263277
let tts = TokenStream::from(tts.clone());

0 commit comments

Comments
 (0)