@@ -779,96 +779,107 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
779779
780780 match expr. kind {
781781 ExprKind :: Call ( _, args) | ExprKind :: MethodCall ( _, _, args) => {
782- let mut args_to_recover = vec ! [ ] ;
783- for arg in args {
784- if is_unit ( cx. tables . expr_ty ( arg) ) && !is_unit_literal ( arg) {
785- if let ExprKind :: Match ( .., match_source) = & arg. kind {
786- if * match_source == MatchSource :: TryDesugar {
787- continue ;
782+ let args_to_recover = args
783+ . iter ( )
784+ . filter ( |arg| {
785+ if is_unit ( cx. tables . expr_ty ( arg) ) && !is_unit_literal ( arg) {
786+ if let ExprKind :: Match ( .., MatchSource :: TryDesugar ) = & arg. kind {
787+ false
788+ } else {
789+ true
788790 }
791+ } else {
792+ false
789793 }
790-
791- args_to_recover. push ( arg) ;
792- }
793- }
794+ } )
795+ . collect :: < Vec < _ > > ( ) ;
794796 if !args_to_recover. is_empty ( ) {
795- let mut applicability = Applicability :: MachineApplicable ;
796- span_lint_and_then ( cx, UNIT_ARG , expr. span , "passing a unit value to a function" , |db| {
797- let mut or = "" ;
798- args_to_recover
799- . iter ( )
800- . filter_map ( |arg| {
801- if_chain ! {
802- if let ExprKind :: Block ( block, _) = arg. kind;
803- if block. expr. is_none( ) ;
804- if let Some ( last_stmt) = block. stmts. iter( ) . last( ) ;
805- if let StmtKind :: Semi ( last_expr) = last_stmt. kind;
806- if let Some ( snip) = snippet_opt( cx, last_expr. span) ;
807- then {
808- Some ( (
809- last_stmt. span,
810- snip,
811- ) )
812- }
813- else {
814- None
815- }
816- }
817- } )
818- . for_each ( |( span, sugg) | {
819- db. span_suggestion (
820- span,
821- "remove the semicolon from the last statement in the block" ,
822- sugg,
823- Applicability :: MaybeIncorrect ,
824- ) ;
825- or = "or " ;
826- } ) ;
827- let sugg = args_to_recover
828- . iter ( )
829- . enumerate ( )
830- . map ( |( i, arg) | {
831- let indent = if i == 0 {
832- 0
833- } else {
834- indent_of ( cx, expr. span ) . unwrap_or ( 0 )
835- } ;
836- format ! (
837- "{}{};" ,
838- " " . repeat( indent) ,
839- snippet_block_with_applicability(
840- cx,
841- arg. span,
842- ".." ,
843- Some ( expr. span) ,
844- & mut applicability
845- )
846- )
847- } )
848- . collect :: < Vec < String > > ( )
849- . join ( "\n " ) ;
850- db. span_suggestion (
851- expr. span . with_hi ( expr. span . lo ( ) ) ,
852- & format ! ( "{}move the expressions in front of the call..." , or) ,
853- format ! ( "{}\n " , sugg) ,
854- applicability,
855- ) ;
856- db. multipart_suggestion (
857- "...and use unit literals instead" ,
858- args_to_recover
859- . iter ( )
860- . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
861- . collect :: < Vec < _ > > ( ) ,
862- applicability,
863- ) ;
864- } ) ;
797+ lint_unit_args ( cx, expr, & args_to_recover) ;
865798 }
866799 } ,
867800 _ => ( ) ,
868801 }
869802 }
870803}
871804
805+ fn lint_unit_args ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > , args_to_recover : & [ & Expr < ' _ > ] ) {
806+ let mut applicability = Applicability :: MachineApplicable ;
807+ let ( singular, plural) = if args_to_recover. len ( ) > 1 {
808+ ( "" , "s" )
809+ } else {
810+ ( "a " , "" )
811+ } ;
812+ span_lint_and_then (
813+ cx,
814+ UNIT_ARG ,
815+ expr. span ,
816+ & format ! ( "passing {}unit value{} to a function" , singular, plural) ,
817+ |db| {
818+ let mut or = "" ;
819+ args_to_recover
820+ . iter ( )
821+ . filter_map ( |arg| {
822+ if_chain ! {
823+ if let ExprKind :: Block ( block, _) = arg. kind;
824+ if block. expr. is_none( ) ;
825+ if let Some ( last_stmt) = block. stmts. iter( ) . last( ) ;
826+ if let StmtKind :: Semi ( last_expr) = last_stmt. kind;
827+ if let Some ( snip) = snippet_opt( cx, last_expr. span) ;
828+ then {
829+ Some ( (
830+ last_stmt. span,
831+ snip,
832+ ) )
833+ }
834+ else {
835+ None
836+ }
837+ }
838+ } )
839+ . for_each ( |( span, sugg) | {
840+ db. span_suggestion (
841+ span,
842+ "remove the semicolon from the last statement in the block" ,
843+ sugg,
844+ Applicability :: MaybeIncorrect ,
845+ ) ;
846+ or = "or " ;
847+ } ) ;
848+ let sugg = args_to_recover
849+ . iter ( )
850+ . enumerate ( )
851+ . map ( |( i, arg) | {
852+ let indent = if i == 0 {
853+ 0
854+ } else {
855+ indent_of ( cx, expr. span ) . unwrap_or ( 0 )
856+ } ;
857+ format ! (
858+ "{}{};" ,
859+ " " . repeat( indent) ,
860+ snippet_block_with_applicability( cx, arg. span, ".." , Some ( expr. span) , & mut applicability)
861+ )
862+ } )
863+ . collect :: < Vec < String > > ( )
864+ . join ( "\n " ) ;
865+ db. span_suggestion (
866+ expr. span . with_hi ( expr. span . lo ( ) ) ,
867+ & format ! ( "{}move the expression{} in front of the call..." , or, plural) ,
868+ format ! ( "{}\n " , sugg) ,
869+ applicability,
870+ ) ;
871+ db. multipart_suggestion (
872+ & format ! ( "...and use {}unit literal{} instead" , singular, plural) ,
873+ args_to_recover
874+ . iter ( )
875+ . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
876+ . collect :: < Vec < _ > > ( ) ,
877+ applicability,
878+ ) ;
879+ } ,
880+ ) ;
881+ }
882+
872883fn is_questionmark_desugar_marked_call ( expr : & Expr < ' _ > ) -> bool {
873884 use rustc_span:: hygiene:: DesugaringKind ;
874885 if let ExprKind :: Call ( ref callee, _) = expr. kind {
0 commit comments