Skip to content

Commit 0693306

Browse files
Rollup merge of #88267 - sexxi-goose:truncate_unique, r=nikomatsakis
2229: Update signature for truncate function r? `@nikomatsakis`
2 parents cc2a127 + ed43e02 commit 0693306

File tree

1 file changed

+48
-70
lines changed

1 file changed

+48
-70
lines changed

compiler/rustc_typeck/src/check/upvar.rs

+48-70
Original file line numberDiff line numberDiff line change
@@ -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.
18431839
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>,
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.
19081902
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>,
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.
19401928
fn 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

19681948
fn 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
/// ```
22582234
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>,
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

Comments
 (0)