Skip to content

Commit 564b4de

Browse files
committed
use the correct attributes and add helper function
1 parent acfc708 commit 564b4de

File tree

2 files changed

+80
-98
lines changed

2 files changed

+80
-98
lines changed

compiler/rustc_typeck/src/check/upvar.rs

+78-96
Original file line numberDiff line numberDiff line change
@@ -583,129 +583,111 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
583583
self.infcx.predicate_may_hold(&obligation)
584584
}
585585

586-
/// Figures out the list of root variables (and their types) that aren't completely
587-
/// captured by the closure when `capture_disjoint_fields` is enabled and auto-traits
588-
/// differ between the root variable and the captured paths.
589-
///
590-
/// The output list would include a root variable if:
591-
/// - It would have been captured into the closure when `capture_disjoint_fields` wasn't
592-
/// enabled, **and**
593-
/// - It wasn't completely captured by the closure, **and**
594-
/// - One of the paths captured does not implement all the auto-traits its root variable
595-
/// implements.
596-
fn compute_2229_migrations_for_trait(
586+
/// Returns true if migration is needed for trait for the provided var_hir_id
587+
fn need_2229_migrations_for_trait(
597588
&self,
598589
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
599-
_closure_clause: hir::CaptureBy,
600590
var_hir_id: hir::HirId,
601-
) -> Option<FxHashSet<&str>> {
591+
check_trait: Option<DefId>,
592+
) -> bool {
602593
let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
603594
min_captures.and_then(|m| m.get(&var_hir_id))
604595
{
605596
root_var_min_capture_list
606597
} else {
607-
return None;
598+
return false;
608599
};
609600

610601
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
611602

612-
let tcx = self.infcx.tcx;
613-
614603
let cause = ObligationCause::misc(self.tcx.hir().span(var_hir_id), self.body_id);
615604

616-
let clone_obligation_should_hold = tcx
617-
.lang_items()
618-
.clone_trait()
619-
.map(|clone_trait| self.ty_impls_trait(ty, &cause, clone_trait))
620-
.unwrap_or(false);
621-
let sync_obligation_should_hold = tcx
622-
.lang_items()
623-
.sync_trait()
624-
.map(|sync_trait| self.ty_impls_trait(ty, &cause, sync_trait))
625-
.unwrap_or(false);
626-
let send_obligation_should_hold = tcx
627-
.lang_items()
628-
.send_trait()
629-
.map(|send_trait| self.ty_impls_trait(ty, &cause, send_trait))
630-
.unwrap_or(false);
631-
let unpin_obligation_should_hold = tcx
632-
.lang_items()
633-
.unpin_trait()
634-
.map(|unpin_trait| self.ty_impls_trait(ty, &cause, unpin_trait))
635-
.unwrap_or(false);
636-
let unwind_safe_obligation_should_hold = tcx
637-
.lang_items()
638-
.unwind_safe_trait()
639-
.map(|unwind_safe_trait| self.ty_impls_trait(ty, &cause, unwind_safe_trait))
640-
.unwrap_or(false);
641-
let ref_unwind_safe_obligation_should_hold = tcx
642-
.lang_items()
643-
.ref_unwind_safe_trait()
644-
.map(|ref_unwind_safe_trait| self.ty_impls_trait(ty, &cause, ref_unwind_safe_trait))
605+
let obligation_should_hold = check_trait
606+
.map(|check_trait| self.ty_impls_trait(ty, &cause, check_trait))
645607
.unwrap_or(false);
646608

647609
// Check whether catpured fields also implement the trait
648-
let mut auto_trait_reasons = FxHashSet::default();
649610

650611
for capture in root_var_min_capture_list.iter() {
651612
let ty = capture.place.ty();
652613

653-
let clone_obligation_holds_for_capture = tcx
654-
.lang_items()
655-
.clone_trait()
656-
.map(|clone_trait| self.ty_impls_trait(ty, &cause, clone_trait))
657-
.unwrap_or(false);
658-
let sync_obligation_holds_for_capture = tcx
659-
.lang_items()
660-
.sync_trait()
661-
.map(|sync_trait| self.ty_impls_trait(ty, &cause, sync_trait))
662-
.unwrap_or(false);
663-
let send_obligation_holds_for_capture = tcx
664-
.lang_items()
665-
.send_trait()
666-
.map(|send_trait| self.ty_impls_trait(ty, &cause, send_trait))
667-
.unwrap_or(false);
668-
let unpin_obligation_holds_for_capture = tcx
669-
.lang_items()
670-
.unpin_trait()
671-
.map(|unpin_trait| self.ty_impls_trait(ty, &cause, unpin_trait))
672-
.unwrap_or(false);
673-
let unwind_safe_obligation_holds_for_capture = tcx
674-
.lang_items()
675-
.unwind_safe_trait()
676-
.map(|unwind_safe| self.ty_impls_trait(ty, &cause, unwind_safe))
677-
.unwrap_or(false);
678-
let ref_unwind_safe_obligation_holds_for_capture = tcx
679-
.lang_items()
680-
.ref_unwind_safe_trait()
681-
.map(|ref_unwind_safe_trait| self.ty_impls_trait(ty, &cause, ref_unwind_safe_trait))
614+
let obligation_holds_for_capture = check_trait
615+
.map(|check_trait| self.ty_impls_trait(ty, &cause, check_trait))
682616
.unwrap_or(false);
683617

684-
if !clone_obligation_holds_for_capture && clone_obligation_should_hold {
685-
auto_trait_reasons.insert("`Clone`");
618+
if !obligation_holds_for_capture && obligation_should_hold {
619+
return true;
686620
}
621+
}
622+
false
623+
}
687624

688-
if !sync_obligation_holds_for_capture && sync_obligation_should_hold {
689-
auto_trait_reasons.insert("`Sync`");
690-
}
625+
/// Figures out the list of root variables (and their types) that aren't completely
626+
/// captured by the closure when `capture_disjoint_fields` is enabled and auto-traits
627+
/// differ between the root variable and the captured paths.
628+
///
629+
/// The output list would include a root variable if:
630+
/// - It would have been captured into the closure when `capture_disjoint_fields` wasn't
631+
/// enabled, **and**
632+
/// - It wasn't completely captured by the closure, **and**
633+
/// - One of the paths captured does not implement all the auto-traits its root variable
634+
/// implements.
635+
fn compute_2229_migrations_for_trait(
636+
&self,
637+
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
638+
var_hir_id: hir::HirId,
639+
) -> Option<FxHashSet<&str>> {
640+
let tcx = self.infcx.tcx;
691641

692-
if !send_obligation_holds_for_capture && send_obligation_should_hold {
693-
auto_trait_reasons.insert("`Send`");
694-
}
642+
// Check whether catpured fields also implement the trait
643+
let mut auto_trait_reasons = FxHashSet::default();
695644

696-
if !unpin_obligation_holds_for_capture && unpin_obligation_should_hold {
697-
auto_trait_reasons.insert("`Unpin`");
698-
}
645+
if self.need_2229_migrations_for_trait(
646+
min_captures,
647+
var_hir_id,
648+
tcx.lang_items().clone_trait(),
649+
) {
650+
auto_trait_reasons.insert("`Clone`");
651+
}
699652

700-
if !unwind_safe_obligation_holds_for_capture && unwind_safe_obligation_should_hold {
701-
auto_trait_reasons.insert("`UnwindSafe`");
702-
}
653+
if self.need_2229_migrations_for_trait(
654+
min_captures,
655+
var_hir_id,
656+
tcx.lang_items().sync_trait(),
657+
) {
658+
auto_trait_reasons.insert("`Sync`");
659+
}
703660

704-
if !ref_unwind_safe_obligation_holds_for_capture
705-
&& ref_unwind_safe_obligation_should_hold
706-
{
707-
auto_trait_reasons.insert("`RefUnwindSafe`");
708-
}
661+
if self.need_2229_migrations_for_trait(
662+
min_captures,
663+
var_hir_id,
664+
tcx.lang_items().send_trait(),
665+
) {
666+
auto_trait_reasons.insert("`Send`");
667+
}
668+
669+
if self.need_2229_migrations_for_trait(
670+
min_captures,
671+
var_hir_id,
672+
tcx.lang_items().unpin_trait(),
673+
) {
674+
auto_trait_reasons.insert("`Unpin`");
675+
}
676+
677+
if self.need_2229_migrations_for_trait(
678+
min_captures,
679+
var_hir_id,
680+
tcx.lang_items().unwind_safe_trait(),
681+
) {
682+
auto_trait_reasons.insert("`UnwindSafe`");
683+
}
684+
685+
if self.need_2229_migrations_for_trait(
686+
min_captures,
687+
var_hir_id,
688+
tcx.lang_items().ref_unwind_safe_trait(),
689+
) {
690+
auto_trait_reasons.insert("`RefUnwindSafe`");
709691
}
710692

711693
if auto_trait_reasons.len() > 0 {
@@ -796,7 +778,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
796778
/// - One of the paths starting at this root variable, that is not captured needs Drop **or**
797779
/// - One of the paths captured does not implement all the auto-traits its root variable
798780
/// implements.
799-
///
781+
///
800782
/// Returns a tuple containing a vector of HirIds as well as a String containing the reason
801783
/// why root variables whose HirId is contained in the vector should be fully captured.
802784
fn compute_2229_migrations(
@@ -820,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
820802
for (&var_hir_id, _) in upvars.iter() {
821803
let mut need_migration = false;
822804
if let Some(trait_migration_cause) =
823-
self.compute_2229_migrations_for_trait(min_captures, closure_clause, var_hir_id)
805+
self.compute_2229_migrations_for_trait(min_captures, var_hir_id)
824806
{
825807
need_migration = true;
826808
auto_trait_reasons.extend(trait_migration_cause);

library/std/src/panic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
132132
/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
133133
/// implemented for any closed over variables passed to `catch_unwind`.
134134
#[stable(feature = "catch_unwind", since = "1.9.0")]
135-
#[cfg_attr(not(bootstrap), lang = "unwind_safe")]
135+
#[cfg_attr(all(not(bootstrap), not(test)), lang = "unwind_safe")]
136136
#[rustc_on_unimplemented(
137137
message = "the type `{Self}` may not be safely transferred across an unwind boundary",
138138
label = "`{Self}` may not be safely transferred across an unwind boundary"
@@ -148,7 +148,7 @@ pub auto trait UnwindSafe {}
148148
/// This is a "helper marker trait" used to provide impl blocks for the
149149
/// [`UnwindSafe`] trait, for more information see that documentation.
150150
#[stable(feature = "catch_unwind", since = "1.9.0")]
151-
#[cfg_attr(not(bootstrap), lang = "ref_unwind_safe")]
151+
#[cfg_attr(all(not(bootstrap), not(test)), lang = "ref_unwind_safe")]
152152
#[rustc_on_unimplemented(
153153
message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
154154
transferrable across a catch_unwind boundary",

0 commit comments

Comments
 (0)