@@ -660,96 +660,107 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
660660
661661 match expr. kind {
662662 ExprKind :: Call ( _, args) | ExprKind :: MethodCall ( _, _, args) => {
663- let mut args_to_recover = vec ! [ ] ;
664- for arg in args {
665- if is_unit ( cx. tables . expr_ty ( arg) ) && !is_unit_literal ( arg) {
666- if let ExprKind :: Match ( .., match_source) = & arg. kind {
667- if * match_source == MatchSource :: TryDesugar {
668- continue ;
663+ let args_to_recover = args
664+ . iter ( )
665+ . filter ( |arg| {
666+ if is_unit ( cx. tables . expr_ty ( arg) ) && !is_unit_literal ( arg) {
667+ if let ExprKind :: Match ( .., MatchSource :: TryDesugar ) = & arg. kind {
668+ false
669+ } else {
670+ true
669671 }
672+ } else {
673+ false
670674 }
671-
672- args_to_recover. push ( arg) ;
673- }
674- }
675+ } )
676+ . collect :: < Vec < _ > > ( ) ;
675677 if !args_to_recover. is_empty ( ) {
676- let mut applicability = Applicability :: MachineApplicable ;
677- span_lint_and_then ( cx, UNIT_ARG , expr. span , "passing a unit value to a function" , |db| {
678- let mut or = "" ;
679- args_to_recover
680- . iter ( )
681- . filter_map ( |arg| {
682- if_chain ! {
683- if let ExprKind :: Block ( block, _) = arg. kind;
684- if block. expr. is_none( ) ;
685- if let Some ( last_stmt) = block. stmts. iter( ) . last( ) ;
686- if let StmtKind :: Semi ( last_expr) = last_stmt. kind;
687- if let Some ( snip) = snippet_opt( cx, last_expr. span) ;
688- then {
689- Some ( (
690- last_stmt. span,
691- snip,
692- ) )
693- }
694- else {
695- None
696- }
697- }
698- } )
699- . for_each ( |( span, sugg) | {
700- db. span_suggestion (
701- span,
702- "remove the semicolon from the last statement in the block" ,
703- sugg,
704- Applicability :: MaybeIncorrect ,
705- ) ;
706- or = "or " ;
707- } ) ;
708- let sugg = args_to_recover
709- . iter ( )
710- . enumerate ( )
711- . map ( |( i, arg) | {
712- let indent = if i == 0 {
713- 0
714- } else {
715- indent_of ( cx, expr. span ) . unwrap_or ( 0 )
716- } ;
717- format ! (
718- "{}{};" ,
719- " " . repeat( indent) ,
720- snippet_block_with_applicability(
721- cx,
722- arg. span,
723- ".." ,
724- Some ( expr. span) ,
725- & mut applicability
726- )
727- )
728- } )
729- . collect :: < Vec < String > > ( )
730- . join ( "\n " ) ;
731- db. span_suggestion (
732- expr. span . with_hi ( expr. span . lo ( ) ) ,
733- & format ! ( "{}move the expressions in front of the call..." , or) ,
734- format ! ( "{}\n " , sugg) ,
735- applicability,
736- ) ;
737- db. multipart_suggestion (
738- "...and use unit literals instead" ,
739- args_to_recover
740- . iter ( )
741- . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
742- . collect :: < Vec < _ > > ( ) ,
743- applicability,
744- ) ;
745- } ) ;
678+ lint_unit_args ( cx, expr, & args_to_recover) ;
746679 }
747680 } ,
748681 _ => ( ) ,
749682 }
750683 }
751684}
752685
686+ fn lint_unit_args ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > , args_to_recover : & [ & Expr < ' _ > ] ) {
687+ let mut applicability = Applicability :: MachineApplicable ;
688+ let ( singular, plural) = if args_to_recover. len ( ) > 1 {
689+ ( "" , "s" )
690+ } else {
691+ ( "a " , "" )
692+ } ;
693+ span_lint_and_then (
694+ cx,
695+ UNIT_ARG ,
696+ expr. span ,
697+ & format ! ( "passing {}unit value{} to a function" , singular, plural) ,
698+ |db| {
699+ let mut or = "" ;
700+ args_to_recover
701+ . iter ( )
702+ . filter_map ( |arg| {
703+ if_chain ! {
704+ if let ExprKind :: Block ( block, _) = arg. kind;
705+ if block. expr. is_none( ) ;
706+ if let Some ( last_stmt) = block. stmts. iter( ) . last( ) ;
707+ if let StmtKind :: Semi ( last_expr) = last_stmt. kind;
708+ if let Some ( snip) = snippet_opt( cx, last_expr. span) ;
709+ then {
710+ Some ( (
711+ last_stmt. span,
712+ snip,
713+ ) )
714+ }
715+ else {
716+ None
717+ }
718+ }
719+ } )
720+ . for_each ( |( span, sugg) | {
721+ db. span_suggestion (
722+ span,
723+ "remove the semicolon from the last statement in the block" ,
724+ sugg,
725+ Applicability :: MaybeIncorrect ,
726+ ) ;
727+ or = "or " ;
728+ } ) ;
729+ let sugg = args_to_recover
730+ . iter ( )
731+ . enumerate ( )
732+ . map ( |( i, arg) | {
733+ let indent = if i == 0 {
734+ 0
735+ } else {
736+ indent_of ( cx, expr. span ) . unwrap_or ( 0 )
737+ } ;
738+ format ! (
739+ "{}{};" ,
740+ " " . repeat( indent) ,
741+ snippet_block_with_applicability( cx, arg. span, ".." , Some ( expr. span) , & mut applicability)
742+ )
743+ } )
744+ . collect :: < Vec < String > > ( )
745+ . join ( "\n " ) ;
746+ db. span_suggestion (
747+ expr. span . with_hi ( expr. span . lo ( ) ) ,
748+ & format ! ( "{}move the expression{} in front of the call..." , or, plural) ,
749+ format ! ( "{}\n " , sugg) ,
750+ applicability,
751+ ) ;
752+ db. multipart_suggestion (
753+ & format ! ( "...and use {}unit literal{} instead" , singular, plural) ,
754+ args_to_recover
755+ . iter ( )
756+ . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
757+ . collect :: < Vec < _ > > ( ) ,
758+ applicability,
759+ ) ;
760+ } ,
761+ ) ;
762+ }
763+
753764fn is_questionmark_desugar_marked_call ( expr : & Expr < ' _ > ) -> bool {
754765 use rustc_span:: hygiene:: DesugaringKind ;
755766 if let ExprKind :: Call ( ref callee, _) = expr. kind {
0 commit comments