@@ -3,6 +3,7 @@ use if_chain::if_chain;
3
3
use rustc:: lint:: in_external_macro;
4
4
use rustc_lint:: { EarlyContext , EarlyLintPass } ;
5
5
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
6
+ use rustc_span:: source_map:: Span ;
6
7
use syntax:: ast:: * ;
7
8
8
9
declare_clippy_lint ! {
@@ -242,26 +243,36 @@ fn has_unary_equivalent(bin_op: BinOpKind) -> bool {
242
243
bin_op == BinOpKind :: And || bin_op == BinOpKind :: Mul || bin_op == BinOpKind :: Sub
243
244
}
244
245
246
+ fn indentation ( cx : & EarlyContext < ' _ > , span : Span ) -> Option < u64 > {
247
+ let lo = cx. sess . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
248
+ lo. file
249
+ . get_line ( lo. line - 1 /* line numbers in `Loc` are 1-based */ )
250
+ . map ( |line| line[ ..lo. col . 0 ] . chars ( ) . map ( |c| if c == '\t' { 8 } else { 1 } ) . sum ( ) )
251
+ }
252
+
245
253
/// Implementation of the `POSSIBLE_MISSING_COMMA` lint for array
246
254
fn check_array ( cx : & EarlyContext < ' _ > , expr : & Expr ) {
247
255
if let ExprKind :: Array ( ref array) = expr. kind {
248
256
for element in array {
249
- if let ExprKind :: Binary ( ref op, ref lhs, _) = element. kind {
250
- if has_unary_equivalent ( op. node ) && !differing_macro_contexts ( lhs. span , op. span ) {
251
- let space_span = lhs. span . between ( op. span ) ;
252
- if let Some ( space_snippet) = snippet_opt ( cx, space_span) {
253
- let lint_span = lhs. span . with_lo ( lhs. span . hi ( ) ) ;
254
- if space_snippet. contains ( '\n' ) {
255
- span_note_and_lint (
256
- cx,
257
- POSSIBLE_MISSING_COMMA ,
258
- lint_span,
259
- "possibly missing a comma here" ,
260
- lint_span,
261
- "to remove this lint, add a comma or write the expr in a single line" ,
262
- ) ;
263
- }
264
- }
257
+ if_chain ! {
258
+ if let ExprKind :: Binary ( ref op, ref lhs, _) = element. kind;
259
+ if has_unary_equivalent( op. node) && !differing_macro_contexts( lhs. span, op. span) ;
260
+ let space_span = lhs. span. between( op. span) ;
261
+ if let Some ( space_snippet) = snippet_opt( cx, space_span) ;
262
+ let lint_span = lhs. span. with_lo( lhs. span. hi( ) ) ;
263
+ if space_snippet. contains( '\n' ) ;
264
+ if let Some ( lhs_indent) = indentation( cx, lhs. span) ;
265
+ if let Some ( op_indent) = indentation( cx, op. span) ;
266
+ if op_indent <= lhs_indent;
267
+ then {
268
+ span_note_and_lint(
269
+ cx,
270
+ POSSIBLE_MISSING_COMMA ,
271
+ lint_span,
272
+ "possibly missing a comma here" ,
273
+ lint_span,
274
+ "to remove this lint, add a comma or write the expr in a single line" ,
275
+ ) ;
265
276
}
266
277
}
267
278
}
0 commit comments