@@ -670,9 +670,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
670
670
origin = updated. 1 ;
671
671
672
672
let ( place, capture_kind) = match capture_clause {
673
- hir:: CaptureBy :: Value { .. } | hir:: CaptureBy :: Use { .. } => {
674
- adjust_for_move_closure ( place, capture_kind)
675
- }
673
+ hir:: CaptureBy :: Value { .. } => adjust_for_move_closure ( place, capture_kind) ,
674
+ hir:: CaptureBy :: Use { .. } => adjust_for_use_closure ( place, capture_kind) ,
676
675
hir:: CaptureBy :: Ref => adjust_for_non_move_closure ( place, capture_kind) ,
677
676
} ;
678
677
@@ -1307,7 +1306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1307
1306
for captured_place in root_var_min_capture_list. iter ( ) {
1308
1307
match captured_place. info . capture_kind {
1309
1308
// Only care about captures that are moved into the closure
1310
- ty:: UpvarCapture :: ByValue => {
1309
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
1311
1310
projections_list. push ( captured_place. place . projections . as_slice ( ) ) ;
1312
1311
diagnostics_info. insert ( UpvarMigrationInfo :: CapturingPrecise {
1313
1312
source_expr : captured_place. info . path_expr_id ,
@@ -1931,7 +1930,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
1931
1930
region : ty:: Region < ' tcx > ,
1932
1931
) -> Ty < ' tcx > {
1933
1932
match capture_kind {
1934
- ty:: UpvarCapture :: ByValue => ty,
1933
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => ty,
1935
1934
ty:: UpvarCapture :: ByRef ( kind) => Ty :: new_ref ( tcx, region, ty, kind. to_mutbl_lossy ( ) ) ,
1936
1935
}
1937
1936
}
@@ -2168,6 +2167,20 @@ fn adjust_for_move_closure(
2168
2167
( place, ty:: UpvarCapture :: ByValue )
2169
2168
}
2170
2169
2170
+ /// Truncate deref of any reference.
2171
+ fn adjust_for_use_closure (
2172
+ mut place : Place < ' _ > ,
2173
+ mut kind : ty:: UpvarCapture ,
2174
+ ) -> ( Place < ' _ > , ty:: UpvarCapture ) {
2175
+ let first_deref = place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
2176
+
2177
+ if let Some ( idx) = first_deref {
2178
+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
2179
+ }
2180
+
2181
+ ( place, ty:: UpvarCapture :: ByUse )
2182
+ }
2183
+
2171
2184
/// Adjust closure capture just that if taking ownership of data, only move data
2172
2185
/// from enclosing stack frame.
2173
2186
fn adjust_for_non_move_closure (
@@ -2178,7 +2191,7 @@ fn adjust_for_non_move_closure(
2178
2191
place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
2179
2192
2180
2193
match kind {
2181
- ty:: UpvarCapture :: ByValue => {
2194
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
2182
2195
if let Some ( idx) = contains_deref {
2183
2196
truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
2184
2197
}
@@ -2223,6 +2236,7 @@ fn construct_capture_kind_reason_string<'tcx>(
2223
2236
2224
2237
let capture_kind_str = match capture_info. capture_kind {
2225
2238
ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2239
+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
2226
2240
ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
2227
2241
} ;
2228
2242
@@ -2244,6 +2258,7 @@ fn construct_capture_info_string<'tcx>(
2244
2258
2245
2259
let capture_kind_str = match capture_info. capture_kind {
2246
2260
ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2261
+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
2247
2262
ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
2248
2263
} ;
2249
2264
format ! ( "{place_str} -> {capture_kind_str}" )
@@ -2339,8 +2354,11 @@ fn determine_capture_info(
2339
2354
// expressions.
2340
2355
let eq_capture_kind = match ( capture_info_a. capture_kind , capture_info_b. capture_kind ) {
2341
2356
( ty:: UpvarCapture :: ByValue , ty:: UpvarCapture :: ByValue ) => true ,
2357
+ ( ty:: UpvarCapture :: ByUse , ty:: UpvarCapture :: ByUse ) => true ,
2342
2358
( ty:: UpvarCapture :: ByRef ( ref_a) , ty:: UpvarCapture :: ByRef ( ref_b) ) => ref_a == ref_b,
2343
- ( ty:: UpvarCapture :: ByValue , _) | ( ty:: UpvarCapture :: ByRef ( _) , _) => false ,
2359
+ ( ty:: UpvarCapture :: ByValue , _)
2360
+ | ( ty:: UpvarCapture :: ByUse , _)
2361
+ | ( ty:: UpvarCapture :: ByRef ( _) , _) => false ,
2344
2362
} ;
2345
2363
2346
2364
if eq_capture_kind {
@@ -2350,8 +2368,10 @@ fn determine_capture_info(
2350
2368
}
2351
2369
} else {
2352
2370
// We select the CaptureKind which ranks higher based the following priority order:
2353
- // ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow
2371
+ // (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow
2354
2372
match ( capture_info_a. capture_kind , capture_info_b. capture_kind ) {
2373
+ ( ty:: UpvarCapture :: ByUse , _) => capture_info_a,
2374
+ ( _, ty:: UpvarCapture :: ByUse ) => capture_info_b,
2355
2375
( ty:: UpvarCapture :: ByValue , _) => capture_info_a,
2356
2376
( _, ty:: UpvarCapture :: ByValue ) => capture_info_b,
2357
2377
( ty:: UpvarCapture :: ByRef ( ref_a) , ty:: UpvarCapture :: ByRef ( ref_b) ) => {
@@ -2405,7 +2425,7 @@ fn truncate_place_to_len_and_update_capture_kind<'tcx>(
2405
2425
}
2406
2426
2407
2427
ty:: UpvarCapture :: ByRef ( ..) => { }
2408
- ty:: UpvarCapture :: ByValue => { }
2428
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => { }
2409
2429
}
2410
2430
2411
2431
place. projections . truncate ( len) ;
0 commit comments