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

`}

`