@@ -489,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
489
489
let mut root_var_min_capture_list =
490
490
typeck_results. closure_min_captures . remove ( & closure_def_id) . unwrap_or_default ( ) ;
491
491
492
- for ( place, capture_info) in capture_information. into_iter ( ) {
492
+ for ( mut place, capture_info) in capture_information. into_iter ( ) {
493
493
let var_hir_id = match place. base {
494
494
PlaceBase :: Upvar ( upvar_id) => upvar_id. var_path . hir_id ,
495
495
base => bug ! ( "Expected upvar, found={:?}" , base) ,
@@ -530,14 +530,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
530
530
531
531
// Truncate the descendant (already in min_captures) to be same as the ancestor to handle any
532
532
// 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 ,
536
536
place. projections . len ( ) ,
537
537
) ;
538
538
539
- possible_descendant. info . capture_kind = descendant_capture_kind;
540
-
541
539
updated_capture_info =
542
540
determine_capture_info ( updated_capture_info, possible_descendant. info ) ;
543
541
@@ -561,14 +559,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
561
559
562
560
// Truncate the descendant (current place) to be same as the ancestor to handle any
563
561
// 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 ,
567
565
possible_ancestor. place . projections . len ( ) ,
568
566
) ;
569
567
570
- updated_capture_info. capture_kind = descendant_capture_kind;
571
-
572
568
possible_ancestor. info = determine_capture_info (
573
569
possible_ancestor. info ,
574
570
updated_capture_info,
@@ -1476,7 +1472,7 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
1476
1472
tcx : TyCtxt < ' tcx > ,
1477
1473
param_env : ty:: ParamEnv < ' tcx > ,
1478
1474
place : & Place < ' tcx > ,
1479
- curr_borrow_kind : ty:: UpvarCapture < ' tcx > ,
1475
+ mut curr_borrow_kind : ty:: UpvarCapture < ' tcx > ,
1480
1476
) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1481
1477
let pos = place. projections . iter ( ) . enumerate ( ) . position ( |( i, p) | {
1482
1478
let ty = place. ty_before_projection ( i) ;
@@ -1508,13 +1504,13 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
1508
1504
}
1509
1505
} ) ;
1510
1506
1511
- let place = place. clone ( ) ;
1507
+ let mut place = place. clone ( ) ;
1512
1508
1513
1509
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) ;
1517
1511
}
1512
+
1513
+ ( place, curr_borrow_kind)
1518
1514
}
1519
1515
1520
1516
/// 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> {
1841
1837
/// them completely.
1842
1838
/// - No projections are applied on top of Union ADTs, since these require unsafe blocks.
1843
1839
fn 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 > ,
1846
1842
) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1847
- if place. projections . is_empty ( ) {
1848
- // Nothing to do here
1849
- return ( place, curr_mode) ;
1850
- }
1851
-
1852
1843
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 ) ;
1854
1845
}
1855
1846
1856
1847
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 ) ;
1858
1849
}
1859
1850
1860
1851
for ( i, proj) in place. projections . iter ( ) . enumerate ( ) {
1861
1852
if proj. ty . is_unsafe_ptr ( ) {
1862
1853
// 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 ;
1864
1856
}
1865
1857
1866
1858
if proj. ty . is_union ( ) {
1867
1859
// 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 ;
1869
1862
}
1870
1863
}
1871
1864
@@ -1880,7 +1873,7 @@ fn restrict_capture_precision<'tcx>(
1880
1873
place : Place < ' tcx > ,
1881
1874
curr_mode : ty:: UpvarCapture < ' tcx > ,
1882
1875
) -> ( 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) ;
1884
1877
1885
1878
if place. projections . is_empty ( ) {
1886
1879
// Nothing to do here
@@ -1891,7 +1884,8 @@ fn restrict_capture_precision<'tcx>(
1891
1884
match proj. kind {
1892
1885
ProjectionKind :: Index => {
1893
1886
// 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) ;
1895
1889
}
1896
1890
ProjectionKind :: Deref => { }
1897
1891
ProjectionKind :: Field ( ..) => { } // ignore
@@ -1906,8 +1900,8 @@ fn restrict_capture_precision<'tcx>(
1906
1900
/// (or if closure attempts to move data that it doesn’t own).
1907
1901
/// Note: When taking ownership, only capture data found on the stack.
1908
1902
fn 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 > ,
1911
1905
) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1912
1906
let contains_deref_of_ref = place. deref_tys ( ) . any ( |ty| ty. is_ref ( ) ) ;
1913
1907
let first_deref = place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
@@ -1917,52 +1911,38 @@ fn adjust_for_move_closure<'tcx>(
1917
1911
1918
1912
// If there's any Deref and the data needs to be moved into the closure body,
1919
1913
// 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
+ }
1928
1918
1929
1919
// AMAN: I think we don't need the span inside the ByValue anymore
1930
1920
// we have more detailed span in CaptureInfo
1931
1921
( place, ty:: UpvarCapture :: ByValue ( None ) )
1932
1922
}
1933
-
1934
- _ => ( place, ty:: UpvarCapture :: ByValue ( None ) ) ,
1935
1923
}
1936
1924
}
1937
1925
1938
1926
/// Adjust closure capture just that if taking ownership of data, only move data
1939
1927
/// from enclosing stack frame.
1940
1928
fn adjust_for_non_move_closure < ' tcx > (
1941
- place : Place < ' tcx > ,
1929
+ mut place : Place < ' tcx > ,
1942
1930
mut kind : ty:: UpvarCapture < ' tcx > ,
1943
1931
) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
1944
1932
let contains_deref =
1945
1933
place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
1946
1934
1947
1935
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
+ }
1961
1940
}
1962
1941
1963
- ty:: UpvarCapture :: ByValue ( ..) => ( place, kind) ,
1964
- ty:: UpvarCapture :: ByRef ( ..) => ( place, kind) ,
1942
+ ty:: UpvarCapture :: ByRef ( ..) => { }
1965
1943
}
1944
+
1945
+ ( place, kind)
1966
1946
}
1967
1947
1968
1948
fn construct_place_string ( tcx : TyCtxt < ' _ > , place : & Place < ' tcx > ) -> String {
@@ -2157,15 +2137,13 @@ fn determine_capture_info(
2157
2137
///
2158
2138
/// Note: Capture kind changes from `MutBorrow` to `UniqueImmBorrow` if the truncated part of the `place`
2159
2139
/// 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 > ,
2163
2143
len : usize ,
2164
- ) -> ( Place < ' tcx > , ty :: UpvarCapture < ' tcx > ) {
2144
+ ) {
2165
2145
let is_mut_ref = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Ref ( .., hir:: Mutability :: Mut ) ) ;
2166
2146
2167
- let mut capture_kind = curr_mode;
2168
-
2169
2147
// If the truncated part of the place contains `Deref` of a `&mut` then convert MutBorrow ->
2170
2148
// UniqueImmBorrow
2171
2149
// 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(
2176
2154
if place. projections [ i] . kind == ProjectionKind :: Deref
2177
2155
&& is_mut_ref ( place. ty_before_projection ( i) )
2178
2156
{
2179
- capture_kind = ty:: UpvarCapture :: ByRef ( ty:: UpvarBorrow {
2157
+ * curr_mode = ty:: UpvarCapture :: ByRef ( ty:: UpvarBorrow {
2180
2158
kind : ty:: BorrowKind :: UniqueImmBorrow ,
2181
2159
region,
2182
2160
} ) ;
@@ -2190,8 +2168,6 @@ fn truncate_place_to_len(
2190
2168
}
2191
2169
2192
2170
place. projections . truncate ( len) ;
2193
-
2194
- ( place, capture_kind)
2195
2171
}
2196
2172
2197
2173
/// Determines the Ancestry relationship of Place A relative to Place B
@@ -2256,8 +2232,8 @@ fn determine_place_ancestry_relation(
2256
2232
/// }
2257
2233
/// ```
2258
2234
fn 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 > ,
2261
2237
) -> ( Place < ' tcx > , ty:: UpvarCapture < ' tcx > ) {
2262
2238
let is_shared_ref = |ty : Ty < ' _ > | matches ! ( ty. kind( ) , ty:: Ref ( .., hir:: Mutability :: Not ) ) ;
2263
2239
@@ -2269,10 +2245,12 @@ fn truncate_capture_for_optimization<'tcx>(
2269
2245
match idx {
2270
2246
// If that pointer is a shared reference, then we don't need those fields.
2271
2247
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 )
2273
2249
}
2274
- None | Some ( _) => ( place , curr_mode ) ,
2250
+ None | Some ( _) => { }
2275
2251
}
2252
+
2253
+ ( place, curr_mode)
2276
2254
}
2277
2255
2278
2256
/// Precise capture is enabled if the feature gate `capture_disjoint_fields` is enabled or if
0 commit comments