Skip to content

Commit 7c15fc1

Browse files
committed
Consider capture kind for auto traits migration
1 parent f5e8a7d commit 7c15fc1

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

compiler/rustc_typeck/src/check/upvar.rs

+46-12
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
4242
use rustc_infer::infer::UpvarRegion;
4343
use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind};
4444
use rustc_middle::mir::FakeReadCause;
45-
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarSubsts};
45+
use rustc_middle::ty::{
46+
self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarCapture, UpvarSubsts,
47+
};
4648
use rustc_session::lint;
4749
use rustc_span::sym;
4850
use rustc_span::{MultiSpan, Span, Symbol};
@@ -299,13 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
299301
captured_place.place, upvar_ty, capture, captured_place.mutability,
300302
);
301303

302-
match capture {
303-
ty::UpvarCapture::ByValue(_) => upvar_ty,
304-
ty::UpvarCapture::ByRef(borrow) => self.tcx.mk_ref(
305-
borrow.region,
306-
ty::TypeAndMut { ty: upvar_ty, mutbl: borrow.kind.to_mutbl_lossy() },
307-
),
308-
}
304+
apply_capture_kind_on_capture_ty(self.tcx, upvar_ty, capture)
309305
})
310306
.collect()
311307
}
@@ -582,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
582578
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
583579
var_hir_id: hir::HirId,
584580
check_trait: Option<DefId>,
581+
closure_clause: hir::CaptureBy,
585582
) -> bool {
586583
let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
587584
min_captures.and_then(|m| m.get(&var_hir_id))
@@ -593,6 +590,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
593590

594591
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
595592

593+
let ty = match closure_clause {
594+
hir::CaptureBy::Value => ty, // For move closure the capture kind should be by value
595+
hir::CaptureBy::Ref => {
596+
// For non move closure the capture kind is the max capture kind of all captures
597+
// according to the ordering ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue
598+
let mut max_capture_info = root_var_min_capture_list.first().unwrap().info;
599+
for capture in root_var_min_capture_list.iter() {
600+
max_capture_info = determine_capture_info(max_capture_info, capture.info);
601+
}
602+
603+
apply_capture_kind_on_capture_ty(self.tcx, ty, max_capture_info.capture_kind)
604+
}
605+
};
606+
596607
let obligation_should_hold = check_trait
597608
.map(|check_trait| {
598609
self.infcx
@@ -606,10 +617,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
606617
})
607618
.unwrap_or(false);
608619

609-
// Check whether catpured fields also implement the trait
610-
620+
// Check whether captured fields also implement the trait
611621
for capture in root_var_min_capture_list.iter() {
612-
let ty = capture.place.ty();
622+
let ty = apply_capture_kind_on_capture_ty(
623+
self.tcx,
624+
capture.place.ty(),
625+
capture.info.capture_kind,
626+
);
613627

614628
let obligation_holds_for_capture = check_trait
615629
.map(|check_trait| {
@@ -645,6 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645659
&self,
646660
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
647661
var_hir_id: hir::HirId,
662+
closure_clause: hir::CaptureBy,
648663
) -> Option<FxHashSet<&str>> {
649664
let tcx = self.infcx.tcx;
650665

@@ -655,6 +670,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
655670
min_captures,
656671
var_hir_id,
657672
tcx.lang_items().clone_trait(),
673+
closure_clause,
658674
) {
659675
auto_trait_reasons.insert("`Clone`");
660676
}
@@ -663,6 +679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663679
min_captures,
664680
var_hir_id,
665681
tcx.lang_items().sync_trait(),
682+
closure_clause,
666683
) {
667684
auto_trait_reasons.insert("`Sync`");
668685
}
@@ -671,6 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
671688
min_captures,
672689
var_hir_id,
673690
tcx.get_diagnostic_item(sym::send_trait),
691+
closure_clause,
674692
) {
675693
auto_trait_reasons.insert("`Send`");
676694
}
@@ -679,6 +697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679697
min_captures,
680698
var_hir_id,
681699
tcx.lang_items().unpin_trait(),
700+
closure_clause,
682701
) {
683702
auto_trait_reasons.insert("`Unpin`");
684703
}
@@ -687,6 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
687706
min_captures,
688707
var_hir_id,
689708
tcx.get_diagnostic_item(sym::unwind_safe_trait),
709+
closure_clause,
690710
) {
691711
auto_trait_reasons.insert("`UnwindSafe`");
692712
}
@@ -695,6 +715,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
695715
min_captures,
696716
var_hir_id,
697717
tcx.get_diagnostic_item(sym::ref_unwind_safe_trait),
718+
closure_clause,
698719
) {
699720
auto_trait_reasons.insert("`RefUnwindSafe`");
700721
}
@@ -814,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
814835
for (&var_hir_id, _) in upvars.iter() {
815836
let mut need_migration = false;
816837
if let Some(trait_migration_cause) =
817-
self.compute_2229_migrations_for_trait(min_captures, var_hir_id)
838+
self.compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause)
818839
{
819840
need_migration = true;
820841
auto_trait_reasons.extend(trait_migration_cause);
@@ -1286,6 +1307,19 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
12861307
place
12871308
}
12881309

1310+
/// Returns a Ty that applies the specified capture kind on the provided capture Ty
1311+
fn apply_capture_kind_on_capture_ty(
1312+
tcx: TyCtxt<'tcx>,
1313+
ty: Ty<'tcx>,
1314+
capture_kind: UpvarCapture<'tcx>,
1315+
) -> Ty<'tcx> {
1316+
match capture_kind {
1317+
ty::UpvarCapture::ByValue(_) => ty,
1318+
ty::UpvarCapture::ByRef(borrow) => tcx
1319+
.mk_ref(borrow.region, ty::TypeAndMut { ty: ty, mutbl: borrow.kind.to_mutbl_lossy() }),
1320+
}
1321+
}
1322+
12891323
struct InferBorrowKind<'a, 'tcx> {
12901324
fcx: &'a FnCtxt<'a, 'tcx>,
12911325

src/test/ui/closures/2229_closure_analysis/migrations/unpin_no_migration.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//run-pass
2-
#![deny(disjoint_capture_migration)]
2+
#![deny(rust_2021_incompatible_closure_captures)]
33
#![allow(unused_must_use)]
44

55
fn filter_try_fold(

0 commit comments

Comments
 (0)