11use if_chain:: if_chain;
22use rustc:: hir:: { Expr , ExprKind } ;
33use rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
4- use rustc:: { declare_tool_lint, lint_array} ;
4+ use rustc:: { declare_lint_pass, declare_tool_lint} ;
5+ use syntax_pos:: Span ;
56
67use crate :: consts:: { constant, Constant } ;
7- use crate :: syntax:: ast:: LitKind ;
88use crate :: utils:: { in_macro, is_direct_expn_of, span_help_and_lint} ;
99
1010declare_clippy_lint ! {
@@ -29,55 +29,44 @@ declare_clippy_lint! {
2929 "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
3030}
3131
32- pub struct AssertionsOnConstants ;
33-
34- impl LintPass for AssertionsOnConstants {
35- fn get_lints ( & self ) -> LintArray {
36- lint_array ! [ ASSERTIONS_ON_CONSTANTS ]
37- }
38-
39- fn name ( & self ) -> & ' static str {
40- "AssertionsOnConstants"
41- }
42- }
32+ declare_lint_pass ! ( AssertionsOnConstants => [ ASSERTIONS_ON_CONSTANTS ] ) ;
4333
4434impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for AssertionsOnConstants {
4535 fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , e : & ' tcx Expr ) {
36+ let mut is_debug_assert = false ;
37+ let debug_assert_not_in_macro = |span : Span | {
38+ is_debug_assert = true ;
39+ // Check that `debug_assert!` itself is not inside a macro
40+ !in_macro ( span)
41+ } ;
4642 if_chain ! {
4743 if let Some ( assert_span) = is_direct_expn_of( e. span, "assert" ) ;
4844 if !in_macro( assert_span)
49- || is_direct_expn_of( assert_span, "debug_assert" ) . map_or( false , |span| !in_macro( span) ) ;
45+ || is_direct_expn_of( assert_span, "debug_assert" )
46+ . map_or( false , debug_assert_not_in_macro) ;
5047 if let ExprKind :: Unary ( _, ref lit) = e. node;
48+ if let Some ( bool_const) = constant( cx, cx. tables, lit) ;
5149 then {
52- if let ExprKind :: Lit ( ref inner) = lit. node {
53- match inner. node {
54- LitKind :: Bool ( true ) => {
55- span_help_and_lint( cx, ASSERTIONS_ON_CONSTANTS , e. span,
56- "assert!(true) will be optimized out by the compiler" ,
57- "remove it" ) ;
58- } ,
59- LitKind :: Bool ( false ) => {
60- span_help_and_lint(
61- cx, ASSERTIONS_ON_CONSTANTS , e. span,
62- "assert!(false) should probably be replaced" ,
63- "use panic!() or unreachable!()" ) ;
64- } ,
65- _ => ( ) ,
66- }
67- } else if let Some ( bool_const) = constant( cx, cx. tables, lit) {
68- match bool_const. 0 {
69- Constant :: Bool ( true ) => {
70- span_help_and_lint( cx, ASSERTIONS_ON_CONSTANTS , e. span,
71- "assert!(const: true) will be optimized out by the compiler" ,
72- "remove it" ) ;
73- } ,
74- Constant :: Bool ( false ) => {
75- span_help_and_lint( cx, ASSERTIONS_ON_CONSTANTS , e. span,
76- "assert!(const: false) should probably be replaced" ,
77- "use panic!() or unreachable!()" ) ;
78- } ,
79- _ => ( ) ,
80- }
50+ match bool_const. 0 {
51+ Constant :: Bool ( true ) => {
52+ span_help_and_lint(
53+ cx,
54+ ASSERTIONS_ON_CONSTANTS ,
55+ e. span,
56+ "`assert!(true)` will be optimized out by the compiler" ,
57+ "remove it"
58+ ) ;
59+ } ,
60+ Constant :: Bool ( false ) if !is_debug_assert => {
61+ span_help_and_lint(
62+ cx,
63+ ASSERTIONS_ON_CONSTANTS ,
64+ e. span,
65+ "`assert!(false)` should probably be replaced" ,
66+ "use `panic!()` or `unreachable!()`"
67+ ) ;
68+ } ,
69+ _ => ( ) ,
8170 }
8271 }
8372 }
0 commit comments