@@ -666,9 +666,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
666666 origin = updated. 1 ;
667667
668668 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) ,
672671 hir:: CaptureBy :: Ref => adjust_for_non_move_closure ( place, capture_kind) ,
673672 } ;
674673
@@ -1303,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13031302 for captured_place in root_var_min_capture_list. iter ( ) {
13041303 match captured_place. info . capture_kind {
13051304 // Only care about captures that are moved into the closure
1306- ty:: UpvarCapture :: ByValue => {
1305+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
13071306 projections_list. push ( captured_place. place . projections . as_slice ( ) ) ;
13081307 diagnostics_info. insert ( UpvarMigrationInfo :: CapturingPrecise {
13091308 source_expr : captured_place. info . path_expr_id ,
@@ -1927,7 +1926,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
19271926 region : ty:: Region < ' tcx > ,
19281927) -> Ty < ' tcx > {
19291928 match capture_kind {
1930- ty:: UpvarCapture :: ByValue => ty,
1929+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => ty,
19311930 ty:: UpvarCapture :: ByRef ( kind) => Ty :: new_ref ( tcx, region, ty, kind. to_mutbl_lossy ( ) ) ,
19321931 }
19331932}
@@ -2157,6 +2156,20 @@ fn adjust_for_move_closure(
21572156 ( place, ty:: UpvarCapture :: ByValue )
21582157}
21592158
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+
21602173/// Adjust closure capture just that if taking ownership of data, only move data
21612174/// from enclosing stack frame.
21622175fn adjust_for_non_move_closure (
@@ -2167,7 +2180,7 @@ fn adjust_for_non_move_closure(
21672180 place. projections . iter ( ) . position ( |proj| proj. kind == ProjectionKind :: Deref ) ;
21682181
21692182 match kind {
2170- ty:: UpvarCapture :: ByValue => {
2183+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => {
21712184 if let Some ( idx) = contains_deref {
21722185 truncate_place_to_len_and_update_capture_kind ( & mut place, & mut kind, idx) ;
21732186 }
@@ -2212,6 +2225,7 @@ fn construct_capture_kind_reason_string<'tcx>(
22122225
22132226 let capture_kind_str = match capture_info. capture_kind {
22142227 ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2228+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
22152229 ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
22162230 } ;
22172231
@@ -2233,6 +2247,7 @@ fn construct_capture_info_string<'tcx>(
22332247
22342248 let capture_kind_str = match capture_info. capture_kind {
22352249 ty:: UpvarCapture :: ByValue => "ByValue" . into ( ) ,
2250+ ty:: UpvarCapture :: ByUse => "ByUse" . into ( ) ,
22362251 ty:: UpvarCapture :: ByRef ( kind) => format ! ( "{kind:?}" ) ,
22372252 } ;
22382253 format ! ( "{place_str} -> {capture_kind_str}" )
@@ -2328,8 +2343,11 @@ fn determine_capture_info(
23282343 // expressions.
23292344 let eq_capture_kind = match ( capture_info_a. capture_kind , capture_info_b. capture_kind ) {
23302345 ( ty:: UpvarCapture :: ByValue , ty:: UpvarCapture :: ByValue ) => true ,
2346+ ( ty:: UpvarCapture :: ByUse , ty:: UpvarCapture :: ByUse ) => true ,
23312347 ( 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 ,
23332351 } ;
23342352
23352353 if eq_capture_kind {
@@ -2339,8 +2357,10 @@ fn determine_capture_info(
23392357 }
23402358 } else {
23412359 // We select the CaptureKind which ranks higher based the following priority order:
2342- // ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow
2360+ // ByUse > ByValue > MutBorrow > UniqueImmBorrow > ImmBorrow
23432361 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,
23442364 ( ty:: UpvarCapture :: ByValue , _) => capture_info_a,
23452365 ( _, ty:: UpvarCapture :: ByValue ) => capture_info_b,
23462366 ( ty:: UpvarCapture :: ByRef ( ref_a) , ty:: UpvarCapture :: ByRef ( ref_b) ) => {
@@ -2394,7 +2414,7 @@ fn truncate_place_to_len_and_update_capture_kind<'tcx>(
23942414 }
23952415
23962416 ty:: UpvarCapture :: ByRef ( ..) => { }
2397- ty:: UpvarCapture :: ByValue => { }
2417+ ty:: UpvarCapture :: ByValue | ty :: UpvarCapture :: ByUse => { }
23982418 }
23992419
24002420 place. projections . truncate ( len) ;
0 commit comments