@@ -123,7 +123,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
123123                Origin :: Mir , 
124124            ) ; 
125125
126-             self . add_closure_invoked_twice_with_moved_variable_suggestion ( 
126+             self . add_moved_or_invoked_closure_note ( 
127127                context. loc , 
128128                used_place, 
129129                & mut  err, 
@@ -1329,7 +1329,8 @@ enum StorageDeadOrDrop<'tcx> {
13291329
13301330impl < ' cx ,  ' gcx ,  ' tcx >  MirBorrowckCtxt < ' cx ,  ' gcx ,  ' tcx >  { 
13311331
1332-     /// Adds a suggestion when a closure is invoked twice with a moved variable. 
1332+     /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure 
1333+      /// is moved after being invoked. 
13331334     /// 
13341335     /// ```text 
13351336     /// note: closure cannot be invoked more than once because it moves the variable `dict` out of 
@@ -1339,30 +1340,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13391340     /// LL |         for (key, value) in dict { 
13401341     ///    |                             ^^^^ 
13411342     /// ``` 
1342-      pub ( super )  fn  add_closure_invoked_twice_with_moved_variable_suggestion ( 
1343+      pub ( super )  fn  add_moved_or_invoked_closure_note ( 
13431344        & self , 
13441345        location :  Location , 
13451346        place :  & Place < ' tcx > , 
13461347        diag :  & mut  DiagnosticBuilder < ' _ > , 
13471348    )  { 
1349+         debug ! ( "add_moved_or_invoked_closure_note: location={:?} place={:?}" ,  location,  place) ; 
13481350        let  mut  target = place. local ( ) ; 
1349-         debug ! ( 
1350-             "add_closure_invoked_twice_with_moved_variable_suggestion: location={:?} place={:?} \  
1351-               target={:?}", 
1352-              location,  place,  target, 
1353-         ) ; 
13541351        for  stmt in  & self . mir [ location. block ] . statements [ location. statement_index ..]  { 
1355-             debug ! ( 
1356-                 "add_closure_invoked_twice_with_moved_variable_suggestion: stmt={:?} \  
1357-                   target={:?}", 
1358-                  stmt,  target, 
1359-             ) ; 
1352+             debug ! ( "add_moved_or_invoked_closure_note: stmt={:?} target={:?}" ,  stmt,  target) ; 
13601353            if  let  StatementKind :: Assign ( into,  box Rvalue :: Use ( from) )  = & stmt. kind  { 
1361-                 debug ! ( 
1362-                     "add_closure_invoked_twice_with_moved_variable_suggestion: into={:?} \  
1363-                       from={:?}", 
1364-                      into,  from, 
1365-                 ) ; 
1354+                 debug ! ( "add_fnonce_closure_note: into={:?} from={:?}" ,  into,  from) ; 
13661355                match  from { 
13671356                    Operand :: Copy ( ref  place)  |
13681357                    Operand :: Move ( ref  place)  if  target == place. local ( )  =>
@@ -1372,12 +1361,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13721361            } 
13731362        } 
13741363
1375- 
1364+          // Check if we are attempting to call a closure after it has been invoked. 
13761365        let  terminator = self . mir [ location. block ] . terminator ( ) ; 
1377-         debug ! ( 
1378-             "add_closure_invoked_twice_with_moved_variable_suggestion: terminator={:?}" , 
1379-             terminator, 
1380-         ) ; 
1366+         debug ! ( "add_moved_or_invoked_closure_note: terminator={:?}" ,  terminator) ; 
13811367        if  let  TerminatorKind :: Call  { 
13821368            func :  Operand :: Constant ( box Constant  { 
13831369                literal :  ty:: LazyConst :: Evaluated ( ty:: Const  { 
@@ -1389,41 +1375,59 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13891375            args, 
13901376            ..
13911377        }  = & terminator. kind  { 
1392-             debug ! ( "add_closure_invoked_twice_with_moved_variable_suggestion : id={:?}" ,  id) ; 
1378+             debug ! ( "add_moved_or_invoked_closure_note : id={:?}" ,  id) ; 
13931379            if  self . infcx . tcx . parent ( id)  == self . infcx . tcx . lang_items ( ) . fn_once_trait ( )  { 
13941380                let  closure = match  args. first ( )  { 
13951381                    Some ( Operand :: Copy ( ref  place) )  |
13961382                    Some ( Operand :: Move ( ref  place) )  if  target == place. local ( )  =>
13971383                        place. local ( ) . unwrap ( ) , 
13981384                    _ => return , 
13991385                } ; 
1400-                 debug ! ( 
1401-                     "add_closure_invoked_twice_with_moved_variable_suggestion: closure={:?}" , 
1402-                      closure, 
1403-                 ) ; 
14041386
1405-                 if  let  ty:: TyKind :: Closure ( did,  _substs)  = self . mir . local_decls [ closure] . ty . sty  { 
1406-                     let  node_id = match  self . infcx . tcx . hir ( ) . as_local_node_id ( did)  { 
1407-                         Some ( node_id)  => node_id, 
1408-                         _ => return , 
1409-                     } ; 
1387+                 debug ! ( "add_moved_or_invoked_closure_note: closure={:?}" ,  closure) ; 
1388+                 if  let  ty:: TyKind :: Closure ( did,  _)  = self . mir . local_decls [ closure] . ty . sty  { 
1389+                     let  node_id = self . infcx . tcx . hir ( ) . as_local_node_id ( did) . unwrap ( ) ; 
14101390                    let  hir_id = self . infcx . tcx . hir ( ) . node_to_hir_id ( node_id) ; 
14111391
1412-                     if  let  Some ( ( 
1413-                         span,  name
1414-                     ) )  = self . infcx . tcx . typeck_tables_of ( did) . closure_kind_origins ( ) . get ( hir_id)  { 
1392+                     if  let  Some ( ( span,  name) )  = self . infcx . tcx . typeck_tables_of ( did) 
1393+                         . closure_kind_origins ( ) 
1394+                         . get ( hir_id) 
1395+                     { 
14151396                        diag. span_note ( 
14161397                            * span, 
14171398                            & format ! ( 
1418-                                 "closure cannot be invoked more than once because it \  
1419-                                   moves the  variable `{}` out of its environment", 
1420-                                   name, 
1399+                                 "closure cannot be invoked more than once because it moves the  \  
1400+                                   variable `{}` out of its environment", 
1401+                                 name, 
14211402                            ) , 
14221403                        ) ; 
1404+                         return ; 
14231405                    } 
14241406                } 
14251407            } 
14261408        } 
1409+ 
1410+         // Check if we are just moving a closure after it has been invoked. 
1411+         if  let  Some ( target)  = target { 
1412+             if  let  ty:: TyKind :: Closure ( did,  _)  = self . mir . local_decls [ target] . ty . sty  { 
1413+                 let  node_id = self . infcx . tcx . hir ( ) . as_local_node_id ( did) . unwrap ( ) ; 
1414+                 let  hir_id = self . infcx . tcx . hir ( ) . node_to_hir_id ( node_id) ; 
1415+ 
1416+                 if  let  Some ( ( span,  name) )  = self . infcx . tcx . typeck_tables_of ( did) 
1417+                     . closure_kind_origins ( ) 
1418+                     . get ( hir_id) 
1419+                 { 
1420+                     diag. span_note ( 
1421+                         * span, 
1422+                         & format ! ( 
1423+                             "closure cannot be moved more than once as it is not `Copy` due to \  
1424+                               moving the variable `{}` out of its environment", 
1425+                              name
1426+                         ) , 
1427+                     ) ; 
1428+                 } 
1429+             } 
1430+         } 
14271431    } 
14281432
14291433    /// End-user visible description of `place` if one can be found. If the 
0 commit comments