Auto merge of #127609 - flip1995:clippy-subtree-update, r=Manishearth · rust-lang/rust@5315cbe (original) (raw)
`@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
`
6
6
`use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
`
7
7
`use rustc_middle::lint::in_external_macro;
`
8
8
`use rustc_session::impl_lint_pass;
`
9
``
`-
use rustc_span::Span;
`
10
9
``
11
10
`declare_clippy_lint! {
`
12
11
`/// ### What it does
`
`@@ -41,61 +40,80 @@ impl AlmostCompleteRange {
`
41
40
`}
`
42
41
`impl EarlyLintPass for AlmostCompleteRange {
`
43
42
`fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
`
44
``
`-
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind {
`
45
``
`-
let ctxt = e.span.ctxt();
`
46
``
`-
let sugg = if let Some(start) = walk_span_to_context(start.span, ctxt)
`
47
``
`-
&& let Some(end) = walk_span_to_context(end.span, ctxt)
`
48
``
`-
&& self.msrv.meets(msrvs::RANGE_INCLUSIVE)
`
49
``
`-
{
`
50
``
`-
Some((trim_span(cx.sess().source_map(), start.between(end)), "..="))
`
51
``
`-
} else {
`
52
``
`-
None
`
53
``
`-
};
`
54
``
`-
check_range(cx, e.span, start, end, sugg);
`
``
43
`+
if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
`
``
44
`+
&& is_incomplete_range(start, end)
`
``
45
`+
&& !in_external_macro(cx.sess(), e.span)
`
``
46
`+
{
`
``
47
`+
span_lint_and_then(
`
``
48
`+
cx,
`
``
49
`+
ALMOST_COMPLETE_RANGE,
`
``
50
`+
e.span,
`
``
51
`+
"almost complete ascii range",
`
``
52
`+
|diag| {
`
``
53
`+
let ctxt = e.span.ctxt();
`
``
54
`+
if let Some(start) = walk_span_to_context(start.span, ctxt)
`
``
55
`+
&& let Some(end) = walk_span_to_context(end.span, ctxt)
`
``
56
`+
&& self.msrv.meets(msrvs::RANGE_INCLUSIVE)
`
``
57
`+
{
`
``
58
`+
diag.span_suggestion(
`
``
59
`+
trim_span(cx.sess().source_map(), start.between(end)),
`
``
60
`+
"use an inclusive range",
`
``
61
`+
"..=".to_owned(),
`
``
62
`+
Applicability::MaybeIncorrect,
`
``
63
`+
);
`
``
64
`+
}
`
``
65
`+
},
`
``
66
`+
);
`
55
67
`}
`
56
68
`}
`
57
69
``
58
70
`fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &Pat) {
`
59
71
`if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
`
60
72
` && matches!(kind.node, RangeEnd::Excluded)
`
``
73
`+
&& is_incomplete_range(start, end)
`
``
74
`+
&& !in_external_macro(cx.sess(), p.span)
`
61
75
`{
`
62
``
`-
let sugg = if self.msrv.meets(msrvs::RANGE_INCLUSIVE) {
`
63
``
`-
"..="
`
64
``
`-
} else {
`
65
``
`-
"..."
`
66
``
`-
};
`
67
``
`-
check_range(cx, p.span, start, end, Some((kind.span, sugg)));
`
``
76
`+
span_lint_and_then(
`
``
77
`+
cx,
`
``
78
`+
ALMOST_COMPLETE_RANGE,
`
``
79
`+
p.span,
`
``
80
`+
"almost complete ascii range",
`
``
81
`+
|diag| {
`
``
82
`+
diag.span_suggestion(
`
``
83
`+
kind.span,
`
``
84
`+
"use an inclusive range",
`
``
85
`+
if self.msrv.meets(msrvs::RANGE_INCLUSIVE) {
`
``
86
`+
"..=".to_owned()
`
``
87
`+
} else {
`
``
88
`+
"...".to_owned()
`
``
89
`+
},
`
``
90
`+
Applicability::MaybeIncorrect,
`
``
91
`+
);
`
``
92
`+
},
`
``
93
`+
);
`
68
94
`}
`
69
95
`}
`
70
96
``
71
97
`extract_msrv_attr!(EarlyContext);
`
72
98
`}
`
73
99
``
74
``
`-
fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg: Option<(Span, &str)>) {
`
75
``
`-
if let ExprKind::Lit(start_token_lit) = start.peel_parens().kind
`
76
``
`-
&& let ExprKind::Lit(end_token_lit) = end.peel_parens().kind
`
77
``
`-
&& matches!(
`
78
``
`-
(
`
79
``
`-
LitKind::from_token_lit(start_token_lit),
`
80
``
`-
LitKind::from_token_lit(end_token_lit),
`
81
``
`-
),
`
82
``
`-
(
`
83
``
`-
Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
`
84
``
`-
Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
`
85
``
`-
) | (
`
86
``
`-
Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
`
87
``
`-
Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
`
88
``
`-
) | (
`
89
``
`-
Ok(LitKind::Byte(b'0') | LitKind::Char('0')),
`
90
``
`-
Ok(LitKind::Byte(b'9') | LitKind::Char('9')),
`
``
100
`+
fn is_incomplete_range(start: &Expr, end: &Expr) -> bool {
`
``
101
`+
match (&start.peel_parens().kind, &end.peel_parens().kind) {
`
``
102
`+
(&ExprKind::Lit(start_lit), &ExprKind::Lit(end_lit)) => {
`
``
103
`+
matches!(
`
``
104
`+
(LitKind::from_token_lit(start_lit), LitKind::from_token_lit(end_lit),),
`
``
105
`+
(
`
``
106
`+
Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
`
``
107
`+
Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
`
``
108
`+
) | (
`
``
109
`+
Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
`
``
110
`+
Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
`
``
111
`+
) | (
`
``
112
`+
Ok(LitKind::Byte(b'0') | LitKind::Char('0')),
`
``
113
`+
Ok(LitKind::Byte(b'9') | LitKind::Char('9')),
`
``
114
`+
)
`
91
115
`)
`
92
``
`-
)
`
93
``
`-
&& !in_external_macro(cx.sess(), span)
`
94
``
`-
{
`
95
``
`-
span_lint_and_then(cx, ALMOST_COMPLETE_RANGE, span, "almost complete ascii range", |diag| {
`
96
``
`-
if let Some((span, sugg)) = sugg {
`
97
``
`-
diag.span_suggestion(span, "use an inclusive range", sugg, Applicability::MaybeIncorrect);
`
98
``
`-
}
`
99
``
`-
});
`
``
116
`+
},
`
``
117
`+
_ => false,
`
100
118
`}
`
101
119
`}
`