@@ -489,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
489489 let mut root_var_min_capture_list =
490490 typeck_results. closure_min_captures . remove ( & closure_def_id) . unwrap_or_default ( ) ;
491491
492- for ( place, capture_info) in capture_information. into_iter ( ) {
492+ for ( mut place, capture_info) in capture_information. into_iter ( ) {
493493 let var_hir_id = match place. base {
494494 PlaceBase :: Upvar ( upvar_id) => upvar_id. var_path . hir_id ,
495495 base => bug ! ( "Expected upvar, found={:?}" , base) ,
@@ -530,14 +530,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
530530
531531 // Truncate the descendant (already in min_captures) to be same as the ancestor to handle any
532532 // possible change in capture mode.
533- let ( _ , descendant_capture_kind ) = truncate_place_to_len (
534- possible_descendant. place ,
535- possible_descendant. info . capture_kind ,
533+ truncate_place_to_len_and_update_capture_kind (
534+ & mut possible_descendant. place ,
535+ & mut possible_descendant. info . capture_kind ,
536536 place. projections . len ( ) ,
537537 ) ;
538538
539- possible_descendant. info . capture_kind = descendant_capture_kind;
540-
541539 updated_capture_info =
542540 determine_capture_info ( updated_capture_info, possible_descendant. info ) ;
543541
@@ -561,14 +559,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
561559
562560 // Truncate the descendant (current place) to be same as the ancestor to handle any
563561 // possible change in capture mode.
564- let ( _ , descendant_capture_kind ) = truncate_place_to_len (
565- place. clone ( ) ,
566- updated_capture_info. capture_kind ,
562+ truncate_place_to_len_and_update_capture_kind (
563+ & mut place,
564+ & mut updated_capture_info. capture_kind ,
567565 possible_ancestor. place . projections . len ( ) ,
568566 ) ;
569567
570- updated_capture_info. capture_kind = descendant_capture_kind;
571-
572568 possible_ancestor. info = determine_capture_info (
573569 possible_ancestor. info ,
574570 updated_capture_info,
@@ -1476,7 +1472,7 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
14761472 tcx : TyCtxt < ' tcx > ,
14771473 param_env : ty:: ParamEnv < ' tcx > ,
14781474 place : & Place < ' tcx > ,
1479- curr_borrow_kind : ty:: UpvarCapture < ' tcx > ,
1475+ mut curr_borrow_kind : ty:: UpvarCapture < ' tcx > ,
14801476) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
14811477 let pos = place. projections . iter ( ) . enumerate ( ) . position ( |( i, p) | {
14821478 let ty = place. ty_before_projection ( i) ;
@@ -1508,13 +1504,13 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
15081504 }
15091505 } ) ;
15101506
1511- let place = place. clone ( ) ;
1507+ let mut place = place. clone ( ) ;
15121508
15131509 if let Some ( pos) = pos {
1514- truncate_place_to_len ( place, curr_borrow_kind, pos)
1515- } else {
1516- ( place, curr_borrow_kind)
1510+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_borrow_kind, pos) ;
15171511 }
1512+
1513+ ( place, curr_borrow_kind)
15181514}
15191515
15201516/// Returns a Ty that applies the specified capture kind on the provided capture Ty
@@ -1841,31 +1837,28 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
18411837/// them completely.
18421838/// - No projections are applied on top of Union ADTs, since these require unsafe blocks.
18431839fn restrict_precision_for_unsafe (
1844- place : Place < ' tcx > ,
1845- curr_mode : ty:: UpvarCapture < ' tcx > ,
1840+ mut place : Place < ' tcx > ,
1841+ mut curr_mode : ty:: UpvarCapture < ' tcx > ,
18461842) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1847- if place. projections . is_empty ( ) {
1848- // Nothing to do here
1849- return ( place, curr_mode) ;
1850- }
1851-
18521843 if place. base_ty . is_unsafe_ptr ( ) {
1853- return truncate_place_to_len ( place, curr_mode, 0 ) ;
1844+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, 0 ) ;
18541845 }
18551846
18561847 if place. base_ty . is_union ( ) {
1857- return truncate_place_to_len ( place, curr_mode, 0 ) ;
1848+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, 0 ) ;
18581849 }
18591850
18601851 for ( i, proj) in place. projections . iter ( ) . enumerate ( ) {
18611852 if proj. ty . is_unsafe_ptr ( ) {
18621853 // Don't apply any projections on top of an unsafe ptr.
1863- return truncate_place_to_len ( place, curr_mode, i + 1 ) ;
1854+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, i + 1 ) ;
1855+ break ;
18641856 }
18651857
18661858 if proj. ty . is_union ( ) {
18671859 // Don't capture preicse fields of a union.
1868- return truncate_place_to_len ( place, curr_mode, i + 1 ) ;
1860+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, i + 1 ) ;
1861+ break ;
18691862 }
18701863 }
18711864
@@ -1880,7 +1873,7 @@ fn restrict_capture_precision<'tcx>(
18801873 place : Place < ' tcx > ,
18811874 curr_mode : ty:: UpvarCapture < ' tcx > ,
18821875) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1883- let ( place, curr_mode) = restrict_precision_for_unsafe ( place, curr_mode) ;
1876+ let ( mut place, mut curr_mode) = restrict_precision_for_unsafe ( place, curr_mode) ;
18841877
18851878 if place. projections . is_empty ( ) {
18861879 // Nothing to do here
@@ -1891,7 +1884,8 @@ fn restrict_capture_precision<'tcx>(
18911884 match proj. kind {
18921885 ProjectionKind :: Index => {
18931886 // Arrays are completely captured, so we drop Index projections
1894- return truncate_place_to_len ( place, curr_mode, i) ;
1887+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, i) ;
1888+ return ( place, curr_mode) ;
18951889 }
18961890 ProjectionKind :: Deref => { }
18971891 ProjectionKind :: Field ( ..) => { } // ignore
@@ -1906,8 +1900,8 @@ fn restrict_capture_precision<'tcx>(
19061900/// (or if closure attempts to move data that it doesn’t own).
19071901/// Note: When taking ownership, only capture data found on the stack.
19081902fn adjust_for_move_closure < ' tcx > (
1909- place : Place < ' tcx > ,
1910- kind : ty:: UpvarCapture < ' tcx > ,
1903+ mut place : Place < ' tcx > ,
1904+ mut kind : ty:: UpvarCapture < ' tcx > ,
19111905) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
19121906 let contains_deref_of_ref = place. deref_tys ( ) . any ( |ty| ty. is_ref ( ) ) ;
19131907 let first_deref = place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
@@ -1917,52 +1911,38 @@ fn adjust_for_move_closure<'tcx>(
19171911
19181912 // If there's any Deref and the data needs to be moved into the closure body,
19191913 // or it's a Deref of a Box, truncate the path to the first deref
1920- _ if first_deref. is_some ( ) => {
1921- let place = match first_deref {
1922- Some ( idx) => {
1923- let ( place, _) = truncate_place_to_len ( place, kind, idx) ;
1924- place
1925- }
1926- None => place,
1927- } ;
1914+ _ => {
1915+ if let Some ( idx) = first_deref {
1916+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
1917+ }
19281918
19291919 // AMAN: I think we don't need the span inside the ByValue anymore
19301920 // we have more detailed span in CaptureInfo
19311921 ( place, ty:: UpvarCapture :: ByValue ( None ) )
19321922 }
1933-
1934- _ => ( place, ty:: UpvarCapture :: ByValue ( None ) ) ,
19351923 }
19361924}
19371925
19381926/// Adjust closure capture just that if taking ownership of data, only move data
19391927/// from enclosing stack frame.
19401928fn adjust_for_non_move_closure < ' tcx > (
1941- place : Place < ' tcx > ,
1929+ mut place : Place < ' tcx > ,
19421930 mut kind : ty:: UpvarCapture < ' tcx > ,
19431931) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
19441932 let contains_deref =
19451933 place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
19461934
19471935 match kind {
1948- ty:: UpvarCapture :: ByValue ( ..) if contains_deref. is_some ( ) => {
1949- let place = match contains_deref {
1950- Some ( idx) => {
1951- let ( place, new_kind) = truncate_place_to_len ( place, kind, idx) ;
1952-
1953- kind = new_kind;
1954- place
1955- }
1956- // Because of the if guard on the match on `kind`, we should never get here.
1957- None => unreachable ! ( ) ,
1958- } ;
1959-
1960- ( place, kind)
1936+ ty:: UpvarCapture :: ByValue ( ..) => {
1937+ if let Some ( idx) = contains_deref {
1938+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
1939+ }
19611940 }
19621941
1963- ty:: UpvarCapture :: ByValue ( ..) => ( place, kind) ,
1964- ty:: UpvarCapture :: ByRef ( ..) => ( place, kind) ,
1942+ ty:: UpvarCapture :: ByRef ( ..) => { }
19651943 }
1944+
1945+ ( place, kind)
19661946}
19671947
19681948fn construct_place_string ( tcx : TyCtxt < ' _ > , place : & Place < ' tcx > ) -> String {
@@ -2157,15 +2137,13 @@ fn determine_capture_info(
21572137///
21582138/// Note: Capture kind changes from `MutBorrow` to `UniqueImmBorrow` if the truncated part of the `place`
21592139/// contained `Deref` of `&mut`.
2160- fn truncate_place_to_len (
2161- mut place : Place < ' tcx > ,
2162- curr_mode : ty:: UpvarCapture < ' tcx > ,
2140+ fn truncate_place_to_len_and_update_capture_kind (
2141+ place : & mut Place < ' tcx > ,
2142+ curr_mode : & mut ty:: UpvarCapture < ' tcx > ,
21632143 len : usize ,
2164- ) -> ( Place < ' tcx > , ty :: UpvarCapture < ' tcx > ) {
2144+ ) {
21652145 let is_mut_ref = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Ref ( .., hir:: Mutability :: Mut ) ) ;
21662146
2167- let mut capture_kind = curr_mode;
2168-
21692147 // If the truncated part of the place contains `Deref` of a `&mut` then convert MutBorrow ->
21702148 // UniqueImmBorrow
21712149 // Note that if the place contained Deref of a raw pointer it would've not been MutBorrow, so
@@ -2176,7 +2154,7 @@ fn truncate_place_to_len(
21762154 if place. projections [ i] . kind == ProjectionKind :: Deref
21772155 && is_mut_ref ( place. ty_before_projection ( i) )
21782156 {
2179- capture_kind = ty:: UpvarCapture :: ByRef ( ty:: UpvarBorrow {
2157+ * curr_mode = ty:: UpvarCapture :: ByRef ( ty:: UpvarBorrow {
21802158 kind : ty:: BorrowKind :: UniqueImmBorrow ,
21812159 region,
21822160 } ) ;
@@ -2190,8 +2168,6 @@ fn truncate_place_to_len(
21902168 }
21912169
21922170 place. projections . truncate ( len) ;
2193-
2194- ( place, capture_kind)
21952171}
21962172
21972173/// Determines the Ancestry relationship of Place A relative to Place B
@@ -2256,8 +2232,8 @@ fn determine_place_ancestry_relation(
22562232/// }
22572233/// ```
22582234fn truncate_capture_for_optimization < ' tcx > (
2259- place : Place < ' tcx > ,
2260- curr_mode : ty:: UpvarCapture < ' tcx > ,
2235+ mut place : Place < ' tcx > ,
2236+ mut curr_mode : ty:: UpvarCapture < ' tcx > ,
22612237) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
22622238 let is_shared_ref = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Ref ( .., hir:: Mutability :: Not ) ) ;
22632239
@@ -2269,10 +2245,12 @@ fn truncate_capture_for_optimization<'tcx>(
22692245 match idx {
22702246 // If that pointer is a shared reference, then we don't need those fields.
22712247 Some ( idx) if is_shared_ref ( place. ty_before_projection ( idx) ) => {
2272- truncate_place_to_len ( place, curr_mode, idx + 1 )
2248+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_mode, idx + 1 )
22732249 }
2274- None | Some ( _) => ( place , curr_mode ) ,
2250+ None | Some ( _) => { }
22752251 }
2252+
2253+ ( place, curr_mode)
22762254}
22772255
22782256/// Precise capture is enabled if the feature gate `capture_disjoint_fields` is enabled or if
0 commit comments