@@ -11,8 +11,8 @@ use rustc_hir as hir;
1111use rustc_hir:: intravisit:: { walk_body, walk_expr, walk_ty, FnKind , NestedVisitorMap , Visitor } ;
1212use rustc_hir:: {
1313 BinOpKind , Block , Body , Expr , ExprKind , FnDecl , FnRetTy , FnSig , GenericArg , GenericParamKind , HirId , ImplItem ,
14- ImplItemKind , Item , ItemKind , Lifetime , Local , MatchSource , MutTy , Mutability , QPath , Stmt , StmtKind , TraitFn ,
15- TraitItem , TraitItemKind , TyKind , UnOp ,
14+ ImplItemKind , Item , ItemKind , Lifetime , Local , MatchSource , MutTy , Mutability , Node , QPath , Stmt , StmtKind ,
15+ TraitFn , TraitItem , TraitItemKind , TyKind , UnOp ,
1616} ;
1717use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1818use rustc_middle:: hir:: map:: Map ;
@@ -29,10 +29,10 @@ use rustc_typeck::hir_ty_to_ty;
2929use crate :: consts:: { constant, Constant } ;
3030use crate :: utils:: paths;
3131use crate :: utils:: {
32- clip, comparisons, differing_macro_contexts, higher, in_constant, indent_of , int_bits, is_type_diagnostic_item,
32+ clip, comparisons, differing_macro_contexts, higher, in_constant, int_bits, is_type_diagnostic_item,
3333 last_path_segment, match_def_path, match_path, method_chain_args, multispan_sugg, numeric_literal:: NumericLiteral ,
34- qpath_res, sext, snippet, snippet_block_with_applicability , snippet_opt, snippet_with_applicability,
35- snippet_with_macro_callsite , span_lint , span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
34+ qpath_res, sext, snippet, snippet_opt, snippet_with_applicability, snippet_with_macro_callsite , span_lint ,
35+ span_lint_and_help, span_lint_and_sugg, span_lint_and_then, unsext,
3636} ;
3737
3838declare_clippy_lint ! {
@@ -844,43 +844,54 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
844844 Applicability :: MaybeIncorrect ,
845845 ) ;
846846 or = "or " ;
847+ applicability = Applicability :: MaybeIncorrect ;
847848 } ) ;
848- let sugg = args_to_recover
849+
850+ let arg_snippets: Vec < String > = args_to_recover
851+ . iter ( )
852+ . filter_map ( |arg| snippet_opt ( cx, arg. span ) )
853+ . collect ( ) ;
854+ let arg_snippets_without_empty_blocks: Vec < String > = args_to_recover
849855 . iter ( )
850856 . filter ( |arg| !is_empty_block ( arg) )
851- . enumerate ( )
852- . map ( |( i, arg) | {
853- let indent = if i == 0 {
854- 0
855- } else {
856- indent_of ( cx, expr. span ) . unwrap_or ( 0 )
857- } ;
858- format ! (
859- "{}{};" ,
860- " " . repeat( indent) ,
861- snippet_block_with_applicability( cx, arg. span, ".." , Some ( expr. span) , & mut applicability)
862- )
863- } )
864- . collect :: < Vec < String > > ( ) ;
865- let mut and = "" ;
866- if !sugg. is_empty ( ) {
867- let plural = if sugg. len ( ) > 1 { "s" } else { "" } ;
868- db. span_suggestion (
869- expr. span . with_hi ( expr. span . lo ( ) ) ,
870- & format ! ( "{}move the expression{} in front of the call..." , or, plural) ,
871- format ! ( "{}\n " , sugg. join( "\n " ) ) ,
872- applicability,
873- ) ;
874- and = "...and "
857+ . filter_map ( |arg| snippet_opt ( cx, arg. span ) )
858+ . collect ( ) ;
859+
860+ if let Some ( mut sugg) = snippet_opt ( cx, expr. span ) {
861+ arg_snippets. iter ( ) . for_each ( |arg| {
862+ sugg = sugg. replacen ( arg, "()" , 1 ) ;
863+ } ) ;
864+ sugg = format ! ( "{}{}{}" , arg_snippets_without_empty_blocks. join( "; " ) , "; " , sugg) ;
865+ let parent_node = cx. tcx . hir ( ) . find ( cx. tcx . hir ( ) . get_parent_node ( expr. hir_id ) ) ;
866+ if !matches ! ( parent_node, Some ( Node :: Block ( _) ) ) && !matches ! ( parent_node, Some ( Node :: Stmt ( _) ) ) {
867+ // expr is not in a block statement or result expression position, wrap in a block
868+ sugg = format ! ( "{{ {} }}" , sugg) ;
869+ }
870+
871+ if arg_snippets_without_empty_blocks. is_empty ( ) {
872+ db. multipart_suggestion (
873+ & format ! ( "use {}unit literal{} instead" , singular, plural) ,
874+ args_to_recover
875+ . iter ( )
876+ . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
877+ . collect :: < Vec < _ > > ( ) ,
878+ applicability,
879+ ) ;
880+ } else {
881+ let plural = arg_snippets_without_empty_blocks. len ( ) > 1 ;
882+ let empty_or_s = if plural { "s" } else { "" } ;
883+ let it_or_them = if plural { "them" } else { "it" } ;
884+ db. span_suggestion (
885+ expr. span ,
886+ & format ! (
887+ "{}move the expression{} in front of the call and replace {} with the unit literal `()`" ,
888+ or, empty_or_s, it_or_them
889+ ) ,
890+ sugg,
891+ applicability,
892+ ) ;
893+ }
875894 }
876- db. multipart_suggestion (
877- & format ! ( "{}use {}unit literal{} instead" , and, singular, plural) ,
878- args_to_recover
879- . iter ( )
880- . map ( |arg| ( arg. span , "()" . to_string ( ) ) )
881- . collect :: < Vec < _ > > ( ) ,
882- applicability,
883- ) ;
884895 } ,
885896 ) ;
886897}
@@ -2055,6 +2066,7 @@ impl PartialOrd for FullInt {
20552066 } )
20562067 }
20572068}
2069+
20582070impl Ord for FullInt {
20592071 #[ must_use]
20602072 fn cmp ( & self , other : & Self ) -> Ordering {
0 commit comments