3
3
#![ deny( clippy:: missing_docs_in_private_items) ]
4
4
5
5
use crate :: ty:: is_type_diagnostic_item;
6
- use crate :: { is_expn_of, match_def_path, paths} ;
6
+ use crate :: { is_expn_of, match_def_path, paths, source :: snippet_with_applicability } ;
7
7
use if_chain:: if_chain;
8
8
use rustc_ast:: ast:: { self , LitKind } ;
9
+ use rustc_errors:: Applicability ;
9
10
use rustc_hir as hir;
10
11
use rustc_hir:: {
11
12
Arm , Block , BorrowKind , Expr , ExprKind , HirId , LoopSource , MatchSource , Node , Pat , QPath , StmtKind , UnOp ,
12
13
} ;
13
14
use rustc_lint:: LateContext ;
14
15
use rustc_span:: { sym, symbol, ExpnKind , Span , Symbol } ;
15
16
17
+ use std:: borrow:: Cow ;
18
+
16
19
/// The essential nodes of a desugared for loop as well as the entire span:
17
20
/// `for pat in arg { body }` becomes `(pat, arg, body)`. Return `(pat, arg, body, span)`.
18
21
pub struct ForLoop < ' tcx > {
@@ -419,8 +422,8 @@ pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
419
422
}
420
423
421
424
/// A parsed
422
- /// assert!`, `assert_eq!` or `assert_ne!`,
423
- /// debug_assert!`, `debug_assert_eq!` or `debug_assert_ne!`
425
+ /// ` assert!`, `assert_eq!` or `assert_ne!`,
426
+ /// ` debug_assert!`, `debug_assert_eq!` or `debug_assert_ne!`
424
427
/// macro.
425
428
pub struct AssertExpn < ' tcx > {
426
429
/// the first agrument of the assret e.g. `var` in element `assert!(var, ...)`
@@ -448,14 +451,33 @@ impl<'tcx> AssertExpn<'tcx> {
448
451
if let StmtKind :: Semi ( matchexpr) = block. stmts . get ( 0 ) ?. kind {
449
452
// macros with unique arg: `{debug_}assert!` (e.g., `debug_assert!(some_condition)`)
450
453
if_chain ! {
451
- if let Some ( If { cond, .. } ) = If :: hir( matchexpr) ;
454
+ if let Some ( If { cond, then , .. } ) = If :: hir( matchexpr) ;
452
455
if let ExprKind :: Unary ( UnOp :: Not , condition) = cond. kind;
453
456
then {
454
- return Some ( Self {
455
- first_assert_argument: condition,
456
- second_assert_argument: None ,
457
- format_arg: None , // FIXME actually parse the aguments
458
- } ) ;
457
+ if_chain! {
458
+ if let ExprKind :: Block ( block, _) = then. kind;
459
+ if let [ statement, ..] = block. stmts;
460
+ if let StmtKind :: Expr ( call_assert_failed)
461
+ | StmtKind :: Semi ( call_assert_failed) = statement. kind;
462
+ if let ExprKind :: Call ( _, args_assert_failed) = call_assert_failed. kind;
463
+ if !args_assert_failed. is_empty( ) ;
464
+ if let ExprKind :: Call ( _, [ arg, ..] ) = args_assert_failed[ 0 ] . kind;
465
+ if let Some ( format_arg_expn) = FormatArgsExpn :: parse( arg) ;
466
+ then {
467
+ return Some ( Self {
468
+ first_assert_argument: condition,
469
+ second_assert_argument: None ,
470
+ format_arg: Some ( format_arg_expn) , // FIXME actually parse the aguments
471
+ } ) ;
472
+ }
473
+ else{
474
+ return Some ( Self {
475
+ first_assert_argument: condition,
476
+ second_assert_argument: None ,
477
+ format_arg: None ,
478
+ } ) ;
479
+ }
480
+ }
459
481
}
460
482
}
461
483
@@ -496,7 +518,7 @@ impl<'tcx> AssertExpn<'tcx> {
496
518
if let ExprKind :: Call ( _, args_assert_failed) = call_assert_failed. kind;
497
519
if args_assert_failed. len( ) >= 4 ;
498
520
if let ExprKind :: Call ( _, [ arg, ..] ) = args_assert_failed[ 3 ] . kind;
499
- if let Some ( format_arg_expn) = FormatArgsExpn :: parse( & arg) ;
521
+ if let Some ( format_arg_expn) = FormatArgsExpn :: parse( arg) ;
500
522
then {
501
523
return Some ( AssertExpn {
502
524
first_assert_argument: lhs,
@@ -518,19 +540,49 @@ impl<'tcx> AssertExpn<'tcx> {
518
540
None
519
541
}
520
542
521
- /// Gives the argument as a vector
522
- pub fn argument_vector ( & self ) -> Vec < & ' tcx Expr < ' tcx > > {
543
+ /// Gives the argument in the comparaison as a vector leaving the format
544
+ pub fn assert_arguments ( & self ) -> Vec < & ' tcx Expr < ' tcx > > {
523
545
let mut expr_vec = vec ! [ self . first_assert_argument] ;
524
546
if let Some ( sec_agr) = self . second_assert_argument {
525
547
expr_vec. push ( sec_agr) ;
526
548
}
527
- if let Some ( ref format_arg) = self . format_arg {
528
- expr_vec. push ( format_arg. format_string ) ;
529
- for arg in & format_arg. value_args {
530
- expr_vec. push ( arg)
549
+ expr_vec
550
+ }
551
+
552
+ /// Gives the argument passed to the macro as a string
553
+ pub fn all_arguments_string (
554
+ & self ,
555
+ cx : & LateContext < ' _ > ,
556
+ applicability : & mut Applicability ,
557
+ ) -> Vec < Cow < ' static , str > > {
558
+ let mut vec_arg = vec ! [ snippet_with_applicability(
559
+ cx,
560
+ self . first_assert_argument. span,
561
+ ".." ,
562
+ applicability,
563
+ ) ] ;
564
+ if let Some ( sec_agr) = self . second_assert_argument {
565
+ vec_arg. push ( snippet_with_applicability ( cx, sec_agr. span , ".." , applicability) ) ;
566
+ }
567
+ vec_arg. append ( & mut self . format_arguments ( cx, applicability) ) ;
568
+ vec_arg
569
+ }
570
+
571
+ /// Returns only the format agruments
572
+ pub fn format_arguments ( & self , cx : & LateContext < ' _ > , applicability : & mut Applicability ) -> Vec < Cow < ' static , str > > {
573
+ let mut vec_arg = vec ! [ ] ;
574
+ if let Some ( ref fmt_arg) = self . format_arg {
575
+ vec_arg. push ( snippet_with_applicability (
576
+ cx,
577
+ fmt_arg. format_string_span ,
578
+ ".." ,
579
+ applicability,
580
+ ) ) ;
581
+ for arg in & fmt_arg. value_args {
582
+ vec_arg. push ( snippet_with_applicability ( cx, arg. span , ".." , applicability) ) ;
531
583
}
532
584
}
533
- expr_vec
585
+ vec_arg
534
586
}
535
587
}
536
588
@@ -568,8 +620,6 @@ impl FormatExpn<'tcx> {
568
620
569
621
/// A parsed `format_args!` expansion
570
622
pub struct FormatArgsExpn < ' tcx > {
571
- /// The fist argument, the fromat string, as an expr
572
- pub format_string : & ' tcx Expr < ' tcx > ,
573
623
/// Span of the first argument, the format string
574
624
pub format_string_span : Span ,
575
625
/// Values passed after the format string
@@ -626,7 +676,6 @@ impl FormatArgsExpn<'tcx> {
626
676
if let ExprKind :: Array ( args) = arm. body. kind;
627
677
then {
628
678
Some ( FormatArgsExpn {
629
- format_string: strs_ref,
630
679
format_string_span: strs_ref. span,
631
680
value_args,
632
681
format_string_parts,
0 commit comments