@@ -2130,21 +2130,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21302130                 /// misleading users in cases like `tests/ui/nll/borrowed-temporary-error.rs`. 
21312131                 /// We could expand the analysis to suggest hoising all of the relevant parts of 
21322132                 /// the users' code to make the code compile, but that could be too much. 
2133-                  struct  NestedStatementVisitor  { 
2133+                  /// We found the `prop_expr` by the way to check whether the expression is a `FormatArguments`, 
2134+                  /// which is a special case since it's generated by the compiler. 
2135+                  struct  NestedStatementVisitor < ' tcx >  { 
21342136                    span :  Span , 
21352137                    current :  usize , 
21362138                    found :  usize , 
2139+                     prop_expr :  Option < & ' tcx  hir:: Expr < ' tcx > > , 
21372140                } 
21382141
2139-                 impl < ' tcx >  Visitor < ' tcx >  for  NestedStatementVisitor  { 
2140-                     fn  visit_block ( & mut  self ,  block :  & hir:: Block < ' tcx > )  { 
2142+                 impl < ' tcx >  Visitor < ' tcx >  for  NestedStatementVisitor < ' tcx >  { 
2143+                     fn  visit_block ( & mut  self ,  block :  & ' tcx   hir:: Block < ' tcx > )  { 
21412144                        self . current  += 1 ; 
21422145                        walk_block ( self ,  block) ; 
21432146                        self . current  -= 1 ; 
21442147                    } 
2145-                     fn  visit_expr ( & mut  self ,  expr :  & hir:: Expr < ' tcx > )  { 
2148+                     fn  visit_expr ( & mut  self ,  expr :  & ' tcx   hir:: Expr < ' tcx > )  { 
21462149                        if  self . span  == expr. span . source_callsite ( )  { 
21472150                            self . found  = self . current ; 
2151+                             if  self . prop_expr . is_none ( )  { 
2152+                                 self . prop_expr  = Some ( expr) ; 
2153+                             } 
21482154                        } 
21492155                        walk_expr ( self ,  expr) ; 
21502156                    } 
@@ -2162,22 +2168,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
21622168                            span :  proper_span, 
21632169                            current :  0 , 
21642170                            found :  0 , 
2171+                             prop_expr :  None , 
21652172                        } ; 
21662173                        visitor. visit_stmt ( stmt) ; 
2174+ 
2175+                         let  typeck_results = self . infcx . tcx . typeck ( self . mir_def_id ( ) ) ; 
2176+                         let  expr_ty:  Option < Ty < ' _ > >  = visitor. prop_expr . map ( |expr| typeck_results. expr_ty ( expr) . peel_refs ( ) ) ; 
2177+ 
2178+                         let  is_format_arguments_item =
2179+                             if  let  Some ( expr_ty)  = expr_ty
2180+                                && let  ty:: Adt ( adt,  _)  = expr_ty. kind ( )  { 
2181+                                     self . infcx . tcx . lang_items ( ) . get ( LangItem :: FormatArguments )  == Some ( adt. did ( ) ) 
2182+                                }  else  { 
2183+                                    false 
2184+                                } ; 
2185+ 
21672186                        if  visitor. found  == 0 
21682187                            && stmt. span . contains ( proper_span) 
21692188                            && let  Some ( p)  = sm. span_to_margin ( stmt. span ) 
21702189                            && let  Ok ( s)  = sm. span_to_snippet ( proper_span) 
21712190                        { 
2172-                             let  addition = format ! ( "let binding = {};\n {}" ,  s,  " " . repeat( p) ) ; 
2173-                             err. multipart_suggestion_verbose ( 
2174-                                 msg, 
2175-                                 vec ! [ 
2176-                                     ( stmt. span. shrink_to_lo( ) ,  addition) , 
2177-                                     ( proper_span,  "binding" . to_string( ) ) , 
2178-                                 ] , 
2179-                                 Applicability :: MaybeIncorrect , 
2180-                             ) ; 
2191+                             if  !is_format_arguments_item { 
2192+                                 let  addition = format ! ( "let binding = {};\n {}" ,  s,  " " . repeat( p) ) ; 
2193+                                 err. multipart_suggestion_verbose ( 
2194+                                     msg, 
2195+                                     vec ! [ 
2196+                                         ( stmt. span. shrink_to_lo( ) ,  addition) , 
2197+                                         ( proper_span,  "binding" . to_string( ) ) , 
2198+                                     ] , 
2199+                                     Applicability :: MaybeIncorrect , 
2200+                                 ) ; 
2201+                             }  else  { 
2202+                                 err. note ( "the result of `format_args!` can only be assigned directly if no placeholders in it's arguments are used" ) ; 
2203+                                 err. note ( "to learn more, visit <https://doc.rust-lang.org/std/macro.format_args.html>" ) ; 
2204+                             } 
21812205                            suggested = true ; 
21822206                            break ; 
21832207                        } 
0 commit comments