@@ -34,6 +34,7 @@ use super::FnCtxt;
3434
3535use crate :: expr_use_visitor as euv;
3636use rustc_data_structures:: fx:: FxIndexMap ;
37+ use rustc_errors:: Applicability ;
3738use rustc_hir as hir;
3839use rustc_hir:: def_id:: DefId ;
3940use rustc_hir:: def_id:: LocalDefId ;
@@ -91,7 +92,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
9192 if let hir:: ExprKind :: Closure ( cc, _, body_id, _, _) = expr. kind {
9293 let body = self . fcx . tcx . hir ( ) . body ( body_id) ;
9394 self . visit_body ( body) ;
94- self . fcx . analyze_closure ( expr. hir_id , expr. span , body, cc) ;
95+ self . fcx . analyze_closure ( expr. hir_id , expr. span , body_id , body, cc) ;
9596 }
9697
9798 intravisit:: walk_expr ( self , expr) ;
@@ -104,6 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
104105 & self ,
105106 closure_hir_id : hir:: HirId ,
106107 span : Span ,
108+ body_id : hir:: BodyId ,
107109 body : & ' tcx hir:: Body < ' tcx > ,
108110 capture_clause : hir:: CaptureBy ,
109111 ) {
@@ -167,7 +169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
167169
168170 let closure_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( local_def_id) ;
169171 if should_do_migration_analysis ( self . tcx , closure_hir_id) {
170- self . perform_2229_migration_anaysis ( closure_def_id, capture_clause, span) ;
172+ self . perform_2229_migration_anaysis ( closure_def_id, body_id , capture_clause, span) ;
171173 }
172174
173175 // We now fake capture information for all variables that are mentioned within the closure
@@ -465,6 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
465467 fn perform_2229_migration_anaysis (
466468 & self ,
467469 closure_def_id : DefId ,
470+ body_id : hir:: BodyId ,
468471 capture_clause : hir:: CaptureBy ,
469472 span : Span ,
470473 ) {
@@ -488,7 +491,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
488491 let mut diagnostics_builder = lint. build (
489492 "drop order affected for closure because of `capture_disjoint_fields`" ,
490493 ) ;
491- diagnostics_builder. note ( & migrations_text) ;
494+ let closure_body_span = self . tcx . hir ( ) . span ( body_id. hir_id ) ;
495+ let ( sugg, app) =
496+ match self . tcx . sess . source_map ( ) . span_to_snippet ( closure_body_span) {
497+ Ok ( s) => (
498+ format ! ( "{{ {} {} }}" , migrations_text, s) ,
499+ Applicability :: MachineApplicable ,
500+ ) ,
501+ Err ( _) => ( migrations_text. clone ( ) , Applicability :: HasPlaceholders ) ,
502+ } ;
503+
504+ diagnostics_builder. span_suggestion (
505+ closure_body_span,
506+ & format ! ( "You can restore original behavior adding `{}` to the closure/generator" , migrations_text) ,
507+ sugg,
508+ app,
509+ ) ;
492510 diagnostics_builder. emit ( ) ;
493511 } ,
494512 ) ;
@@ -1517,10 +1535,14 @@ fn should_do_migration_analysis(tcx: TyCtxt<'_>, closure_id: hir::HirId) -> bool
15171535
15181536fn migration_suggestion_for_2229 ( tcx : TyCtxt < ' _ > , need_migrations : & Vec < hir:: HirId > ) -> String {
15191537 let need_migrations_strings =
1520- need_migrations. iter ( ) . map ( |v| format ! ( "{}" , var_name( tcx, * v) ) ) . collect :: < Vec < _ > > ( ) ;
1538+ need_migrations. iter ( ) . map ( |v| format ! ( "& {}" , var_name( tcx, * v) ) ) . collect :: < Vec < _ > > ( ) ;
15211539 let migrations_list_concat = need_migrations_strings. join ( ", " ) ;
15221540
1523- format ! ( "drop(&({}));" , migrations_list_concat)
1541+ if 1 == need_migrations. len ( ) {
1542+ format ! ( "let _ = {};" , migrations_list_concat)
1543+ } else {
1544+ format ! ( "let _ = ({});" , migrations_list_concat)
1545+ }
15241546}
15251547
15261548/// Helper function to determine if we need to escalate CaptureKind from
0 commit comments