@@ -666,9 +666,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
666
666
origin = updated. 1 ;
667
667
668
668
let ( place, capture_kind) = match capture_clause {
669
- hir:: CaptureBy :: Value { .. } | hir:: CaptureBy :: Use { .. } => {
670
- adjust_for_move_closure ( place, capture_kind)
671
- }
669
+ hir:: CaptureBy :: Value { .. } => adjust_for_move_closure ( place, capture_kind) ,
670
+ hir:: CaptureBy :: Use { .. } => adjust_for_use_closure ( place, capture_kind) ,
672
671
hir:: CaptureBy :: Ref => adjust_for_non_move_closure ( place, capture_kind) ,
673
672
} ;
674
673
@@ -1303,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1303
1302
for captured_place in root_var_min_capture_list. iter ( ) {
1304
1303
match captured_place. info . capture_kind {
1305
1304
// Only care about captures that are moved into the closure
1306
- ty:: UpvarCapture :: ByValue => {
1305
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
1307
1306
projections_list. push ( captured_place. place . projections . as_slice ( ) ) ;
1308
1307
diagnostics_info. insert ( UpvarMigrationInfo :: CapturingPrecise {
1309
1308
source_expr : captured_place. info . path_expr_id ,
@@ -1927,7 +1926,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
1927
1926
region : ty:: Region < ' tcx > ,
1928
1927
) -> Ty < ' tcx > {
1929
1928
match capture_kind {
1930
- ty:: UpvarCapture :: ByValue => ty,
1929
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => ty,
1931
1930
ty:: UpvarCapture :: ByRef ( kind) => Ty :: new_ref ( tcx, region, ty, kind. to_mutbl_lossy ( ) ) ,
1932
1931
}
1933
1932
}
@@ -2157,6 +2156,20 @@ fn adjust_for_move_closure(
2157
2156
( place, ty:: UpvarCapture :: ByValue )
2158
2157
}
2159
2158
2159
+ /// Truncate deref of any reference.
2160
+ fn adjust_for_use_closure (
2161
+ mut place : Place < ' _ > ,
2162
+ mut kind : ty:: UpvarCapture ,
2163
+ ) -> ( Place < ' _ > , ty:: UpvarCapture ) {
2164
+ let first_deref = place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
2165
+
2166
+ if let Some ( idx) = first_deref {
2167
+ truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
2168
+ }
2169
+
2170
+ ( place, ty:: UpvarCapture :: ByUse )
2171
+ }
2172
+
2160
2173
/// Adjust closure capture just that if taking ownership of data, only move data
2161
2174
/// from enclosing stack frame.
2162
2175
fn adjust_for_non_move_closure (
@@ -2167,7 +2180,7 @@ fn adjust_for_non_move_closure(
2167
2180
place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
2168
2181
2169
2182
match kind {
2170
- ty:: UpvarCapture :: ByValue => {
2183
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
2171
2184
if let Some ( idx) = contains_deref {
2172
2185
truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
2173
2186
}
@@ -2212,6 +2225,7 @@ fn construct_capture_kind_reason_string<'tcx>(
2212
2225
2213
2226
let capture_kind_str = match capture_info. capture_kind {
2214
2227
ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2228
+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
2215
2229
ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
2216
2230
} ;
2217
2231
@@ -2233,6 +2247,7 @@ fn construct_capture_info_string<'tcx>(
2233
2247
2234
2248
let capture_kind_str = match capture_info. capture_kind {
2235
2249
ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2250
+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
2236
2251
ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
2237
2252
} ;
2238
2253
format ! ( "{place_str} -> {capture_kind_str}" )
@@ -2328,8 +2343,11 @@ fn determine_capture_info(
2328
2343
// expressions.
2329
2344
let eq_capture_kind = match ( capture_info_a. capture_kind , capture_info_b. capture_kind ) {
2330
2345
( ty:: UpvarCapture :: ByValue , ty:: UpvarCapture :: ByValue ) => true ,
2346
+ ( ty:: UpvarCapture :: ByUse , ty:: UpvarCapture :: ByUse ) => true ,
2331
2347
( ty:: UpvarCapture :: ByRef ( ref_a) , ty:: UpvarCapture :: ByRef ( ref_b) ) => ref_a == ref_b,
2332
- ( ty:: UpvarCapture :: ByValue , _) | ( ty:: UpvarCapture :: ByRef ( _) , _) => false ,
2348
+ ( ty:: UpvarCapture :: ByValue , _)
2349
+ | ( ty:: UpvarCapture :: ByUse , _)
2350
+ | ( ty:: UpvarCapture :: ByRef ( _) , _) => false ,
2333
2351
} ;
2334
2352
2335
2353
if eq_capture_kind {
@@ -2339,8 +2357,10 @@ fn determine_capture_info(
2339
2357
}
2340
2358
} else {
2341
2359
// We select the CaptureKind which ranks higher based the following priority order:
2342
- // ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow
2360
+ // ByUse > ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow
2343
2361
match ( capture_info_a. capture_kind , capture_info_b. capture_kind ) {
2362
+ ( ty:: UpvarCapture :: ByUse , _) => capture_info_a,
2363
+ ( _, ty:: UpvarCapture :: ByUse ) => capture_info_b,
2344
2364
( ty:: UpvarCapture :: ByValue , _) => capture_info_a,
2345
2365
( _, ty:: UpvarCapture :: ByValue ) => capture_info_b,
2346
2366
( ty:: UpvarCapture :: ByRef ( ref_a) , ty:: UpvarCapture :: ByRef ( ref_b) ) => {
@@ -2394,7 +2414,7 @@ fn truncate_place_to_len_and_update_capture_kind<'tcx>(
2394
2414
}
2395
2415
2396
2416
ty:: UpvarCapture :: ByRef ( ..) => { }
2397
- ty:: UpvarCapture :: ByValue => { }
2417
+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => { }
2398
2418
}
2399
2419
2400
2420
place. projections . truncate ( len) ;
0 commit comments