@@ -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,38 @@ 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
+ cx. sess
248
+ . source_map ( )
249
+ . lookup_char_pos ( span. lo ( ) )
250
+ . file
251
+ . get_line ( lo. line - 1 /* line numbers in `Loc` are 1-based */ )
252
+ . map ( |line| line[ ..lo. col . 0 ] . chars ( ) . map ( |c| if c == '\t' { 8 } else { 1 } ) . sum ( ) )
253
+ }
254
+
245
255
/// Implementation of the `POSSIBLE_MISSING_COMMA` lint for array
246
256
fn check_array ( cx : & EarlyContext < ' _ > , expr : & Expr ) {
247
257
if let ExprKind :: Array ( ref array) = expr. kind {
248
258
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
- }
259
+ if_chain ! {
260
+ if let ExprKind :: Binary ( ref op, ref lhs, _) = element. kind;
261
+ if has_unary_equivalent( op. node) && !differing_macro_contexts( lhs. span, op. span) ;
262
+ let space_span = lhs. span. between( op. span) ;
263
+ if let Some ( space_snippet) = snippet_opt( cx, space_span) ;
264
+ let lint_span = lhs. span. with_lo( lhs. span. hi( ) ) ;
265
+ if space_snippet. contains( '\n' ) ;
266
+ if let Some ( lhs_indent) = indentation( cx, lhs. span) ;
267
+ if let Some ( op_indent) = indentation( cx, op. span) ;
268
+ if op_indent <= lhs_indent;
269
+ then {
270
+ span_note_and_lint(
271
+ cx,
272
+ POSSIBLE_MISSING_COMMA ,
273
+ lint_span,
274
+ "possibly missing a comma here" ,
275
+ lint_span,
276
+ "to remove this lint, add a comma or write the expr in a single line" ,
277
+ ) ;
265
278
}
266
279
}
267
280
}
0 commit comments