use the correct attributes and add helper function
This commit is contained in:
parent
acfc708b7c
commit
564b4de626
2 changed files with 84 additions and 102 deletions
|
@ -583,6 +583,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.infcx.predicate_may_hold(&obligation)
|
self.infcx.predicate_may_hold(&obligation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if migration is needed for trait for the provided var_hir_id
|
||||||
|
fn need_2229_migrations_for_trait(
|
||||||
|
&self,
|
||||||
|
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
|
||||||
|
var_hir_id: hir::HirId,
|
||||||
|
check_trait: Option<DefId>,
|
||||||
|
) -> bool {
|
||||||
|
let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
|
||||||
|
min_captures.and_then(|m| m.get(&var_hir_id))
|
||||||
|
{
|
||||||
|
root_var_min_capture_list
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||||
|
|
||||||
|
let cause = ObligationCause::misc(self.tcx.hir().span(var_hir_id), self.body_id);
|
||||||
|
|
||||||
|
let obligation_should_hold = check_trait
|
||||||
|
.map(|check_trait| self.ty_impls_trait(ty, &cause, check_trait))
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
// Check whether catpured fields also implement the trait
|
||||||
|
|
||||||
|
for capture in root_var_min_capture_list.iter() {
|
||||||
|
let ty = capture.place.ty();
|
||||||
|
|
||||||
|
let obligation_holds_for_capture = check_trait
|
||||||
|
.map(|check_trait| self.ty_impls_trait(ty, &cause, check_trait))
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if !obligation_holds_for_capture && obligation_should_hold {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Figures out the list of root variables (and their types) that aren't completely
|
/// Figures out the list of root variables (and their types) that aren't completely
|
||||||
/// captured by the closure when `capture_disjoint_fields` is enabled and auto-traits
|
/// captured by the closure when `capture_disjoint_fields` is enabled and auto-traits
|
||||||
/// differ between the root variable and the captured paths.
|
/// differ between the root variable and the captured paths.
|
||||||
|
@ -596,117 +635,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn compute_2229_migrations_for_trait(
|
fn compute_2229_migrations_for_trait(
|
||||||
&self,
|
&self,
|
||||||
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
|
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
|
||||||
_closure_clause: hir::CaptureBy,
|
|
||||||
var_hir_id: hir::HirId,
|
var_hir_id: hir::HirId,
|
||||||
) -> Option<FxHashSet<&str>> {
|
) -> Option<FxHashSet<&str>> {
|
||||||
let root_var_min_capture_list = if let Some(root_var_min_capture_list) =
|
|
||||||
min_captures.and_then(|m| m.get(&var_hir_id))
|
|
||||||
{
|
|
||||||
root_var_min_capture_list
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
|
||||||
|
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
|
||||||
let cause = ObligationCause::misc(self.tcx.hir().span(var_hir_id), self.body_id);
|
|
||||||
|
|
||||||
let clone_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.clone_trait()
|
|
||||||
.map(|clone_trait| self.ty_impls_trait(ty, &cause, clone_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let sync_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.sync_trait()
|
|
||||||
.map(|sync_trait| self.ty_impls_trait(ty, &cause, sync_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let send_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.send_trait()
|
|
||||||
.map(|send_trait| self.ty_impls_trait(ty, &cause, send_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let unpin_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.unpin_trait()
|
|
||||||
.map(|unpin_trait| self.ty_impls_trait(ty, &cause, unpin_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let unwind_safe_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.unwind_safe_trait()
|
|
||||||
.map(|unwind_safe_trait| self.ty_impls_trait(ty, &cause, unwind_safe_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let ref_unwind_safe_obligation_should_hold = tcx
|
|
||||||
.lang_items()
|
|
||||||
.ref_unwind_safe_trait()
|
|
||||||
.map(|ref_unwind_safe_trait| self.ty_impls_trait(ty, &cause, ref_unwind_safe_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
// Check whether catpured fields also implement the trait
|
// Check whether catpured fields also implement the trait
|
||||||
let mut auto_trait_reasons = FxHashSet::default();
|
let mut auto_trait_reasons = FxHashSet::default();
|
||||||
|
|
||||||
for capture in root_var_min_capture_list.iter() {
|
if self.need_2229_migrations_for_trait(
|
||||||
let ty = capture.place.ty();
|
min_captures,
|
||||||
|
var_hir_id,
|
||||||
let clone_obligation_holds_for_capture = tcx
|
tcx.lang_items().clone_trait(),
|
||||||
.lang_items()
|
) {
|
||||||
.clone_trait()
|
|
||||||
.map(|clone_trait| self.ty_impls_trait(ty, &cause, clone_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let sync_obligation_holds_for_capture = tcx
|
|
||||||
.lang_items()
|
|
||||||
.sync_trait()
|
|
||||||
.map(|sync_trait| self.ty_impls_trait(ty, &cause, sync_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let send_obligation_holds_for_capture = tcx
|
|
||||||
.lang_items()
|
|
||||||
.send_trait()
|
|
||||||
.map(|send_trait| self.ty_impls_trait(ty, &cause, send_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let unpin_obligation_holds_for_capture = tcx
|
|
||||||
.lang_items()
|
|
||||||
.unpin_trait()
|
|
||||||
.map(|unpin_trait| self.ty_impls_trait(ty, &cause, unpin_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let unwind_safe_obligation_holds_for_capture = tcx
|
|
||||||
.lang_items()
|
|
||||||
.unwind_safe_trait()
|
|
||||||
.map(|unwind_safe| self.ty_impls_trait(ty, &cause, unwind_safe))
|
|
||||||
.unwrap_or(false);
|
|
||||||
let ref_unwind_safe_obligation_holds_for_capture = tcx
|
|
||||||
.lang_items()
|
|
||||||
.ref_unwind_safe_trait()
|
|
||||||
.map(|ref_unwind_safe_trait| self.ty_impls_trait(ty, &cause, ref_unwind_safe_trait))
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if !clone_obligation_holds_for_capture && clone_obligation_should_hold {
|
|
||||||
auto_trait_reasons.insert("`Clone`");
|
auto_trait_reasons.insert("`Clone`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sync_obligation_holds_for_capture && sync_obligation_should_hold {
|
if self.need_2229_migrations_for_trait(
|
||||||
|
min_captures,
|
||||||
|
var_hir_id,
|
||||||
|
tcx.lang_items().sync_trait(),
|
||||||
|
) {
|
||||||
auto_trait_reasons.insert("`Sync`");
|
auto_trait_reasons.insert("`Sync`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !send_obligation_holds_for_capture && send_obligation_should_hold {
|
if self.need_2229_migrations_for_trait(
|
||||||
|
min_captures,
|
||||||
|
var_hir_id,
|
||||||
|
tcx.lang_items().send_trait(),
|
||||||
|
) {
|
||||||
auto_trait_reasons.insert("`Send`");
|
auto_trait_reasons.insert("`Send`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unpin_obligation_holds_for_capture && unpin_obligation_should_hold {
|
if self.need_2229_migrations_for_trait(
|
||||||
|
min_captures,
|
||||||
|
var_hir_id,
|
||||||
|
tcx.lang_items().unpin_trait(),
|
||||||
|
) {
|
||||||
auto_trait_reasons.insert("`Unpin`");
|
auto_trait_reasons.insert("`Unpin`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unwind_safe_obligation_holds_for_capture && unwind_safe_obligation_should_hold {
|
if self.need_2229_migrations_for_trait(
|
||||||
|
min_captures,
|
||||||
|
var_hir_id,
|
||||||
|
tcx.lang_items().unwind_safe_trait(),
|
||||||
|
) {
|
||||||
auto_trait_reasons.insert("`UnwindSafe`");
|
auto_trait_reasons.insert("`UnwindSafe`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ref_unwind_safe_obligation_holds_for_capture
|
if self.need_2229_migrations_for_trait(
|
||||||
&& ref_unwind_safe_obligation_should_hold
|
min_captures,
|
||||||
{
|
var_hir_id,
|
||||||
|
tcx.lang_items().ref_unwind_safe_trait(),
|
||||||
|
) {
|
||||||
auto_trait_reasons.insert("`RefUnwindSafe`");
|
auto_trait_reasons.insert("`RefUnwindSafe`");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if auto_trait_reasons.len() > 0 {
|
if auto_trait_reasons.len() > 0 {
|
||||||
return Some(auto_trait_reasons);
|
return Some(auto_trait_reasons);
|
||||||
|
@ -820,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
for (&var_hir_id, _) in upvars.iter() {
|
for (&var_hir_id, _) in upvars.iter() {
|
||||||
let mut need_migration = false;
|
let mut need_migration = false;
|
||||||
if let Some(trait_migration_cause) =
|
if let Some(trait_migration_cause) =
|
||||||
self.compute_2229_migrations_for_trait(min_captures, closure_clause, var_hir_id)
|
self.compute_2229_migrations_for_trait(min_captures, var_hir_id)
|
||||||
{
|
{
|
||||||
need_migration = true;
|
need_migration = true;
|
||||||
auto_trait_reasons.extend(trait_migration_cause);
|
auto_trait_reasons.extend(trait_migration_cause);
|
||||||
|
|
|
@ -132,7 +132,7 @@ pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
|
||||||
/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
|
/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
|
||||||
/// implemented for any closed over variables passed to `catch_unwind`.
|
/// implemented for any closed over variables passed to `catch_unwind`.
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "unwind_safe")]
|
#[cfg_attr(all(not(bootstrap), not(test)), lang = "unwind_safe")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "the type `{Self}` may not be safely transferred across an unwind boundary",
|
message = "the type `{Self}` may not be safely transferred across an unwind boundary",
|
||||||
label = "`{Self}` may not be safely transferred across an unwind boundary"
|
label = "`{Self}` may not be safely transferred across an unwind boundary"
|
||||||
|
@ -148,7 +148,7 @@ pub auto trait UnwindSafe {}
|
||||||
/// This is a "helper marker trait" used to provide impl blocks for the
|
/// This is a "helper marker trait" used to provide impl blocks for the
|
||||||
/// [`UnwindSafe`] trait, for more information see that documentation.
|
/// [`UnwindSafe`] trait, for more information see that documentation.
|
||||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "ref_unwind_safe")]
|
#[cfg_attr(all(not(bootstrap), not(test)), lang = "ref_unwind_safe")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
|
message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
|
||||||
transferrable across a catch_unwind boundary",
|
transferrable across a catch_unwind boundary",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue