Do check_coroutine_obligations once per typeck root
This commit is contained in:
parent
aa1653e5be
commit
d29178c2ef
@ -10,10 +10,9 @@
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::Node;
|
||||
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
|
||||
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
|
||||
@ -26,7 +25,7 @@
|
||||
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
|
||||
use rustc_trait_selection::traits::{self};
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
|
||||
use std::cell::LazyCell;
|
||||
@ -1541,55 +1540,31 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||
err.emit()
|
||||
}
|
||||
|
||||
// FIXME(@lcnr): This should not be computed per coroutine, but instead once for
|
||||
// each typeck root.
|
||||
pub(super) fn check_coroutine_obligations(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: LocalDefId,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
debug_assert!(tcx.is_coroutine(def_id.to_def_id()));
|
||||
debug_assert!(!tcx.is_typeck_child(def_id.to_def_id()));
|
||||
|
||||
let typeck = tcx.typeck(def_id);
|
||||
let param_env = tcx.param_env(typeck.hir_owner.def_id);
|
||||
let typeck_results = tcx.typeck(def_id);
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let coroutine_stalled_predicates = &typeck.coroutine_stalled_predicates[&def_id];
|
||||
debug!(?coroutine_stalled_predicates);
|
||||
debug!(?typeck_results.coroutine_stalled_predicates);
|
||||
|
||||
let infcx = tcx
|
||||
.infer_ctxt()
|
||||
// typeck writeback gives us predicates with their regions erased.
|
||||
// As borrowck already has checked lifetimes, we do not need to do it again.
|
||||
.ignoring_regions()
|
||||
// Bind opaque types to type checking root, as they should have been checked by borrowck,
|
||||
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
|
||||
.with_opaque_type_inference(typeck.hir_owner.def_id)
|
||||
.with_opaque_type_inference(def_id)
|
||||
.build();
|
||||
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
|
||||
for (predicate, cause) in coroutine_stalled_predicates {
|
||||
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
|
||||
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
for (predicate, cause) in &typeck_results.coroutine_stalled_predicates {
|
||||
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate));
|
||||
}
|
||||
|
||||
if (tcx.features().unsized_locals || tcx.features().unsized_fn_params)
|
||||
&& let Some(coroutine) = tcx.mir_coroutine_witnesses(def_id)
|
||||
{
|
||||
for field_ty in coroutine.field_tys.iter() {
|
||||
fulfillment_cx.register_bound(
|
||||
&infcx,
|
||||
param_env,
|
||||
field_ty.ty,
|
||||
tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
|
||||
ObligationCause::new(
|
||||
field_ty.source_info.span,
|
||||
def_id,
|
||||
ObligationCauseCode::SizedCoroutineInterior(def_id),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
|
@ -575,12 +575,8 @@ pub(in super::super) fn resolve_coroutine_interiors(&self) {
|
||||
obligations
|
||||
.extend(self.fulfillment_cx.borrow_mut().drain_unstalled_obligations(&self.infcx));
|
||||
|
||||
let obligations = obligations.into_iter().map(|o| (o.predicate, o.cause)).collect();
|
||||
debug!(?obligations);
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.coroutine_stalled_predicates
|
||||
.insert(expr_def_id, obligations);
|
||||
let obligations = obligations.into_iter().map(|o| (o.predicate, o.cause));
|
||||
self.typeck_results.borrow_mut().coroutine_stalled_predicates.extend(obligations);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,15 +550,10 @@ fn visit_user_provided_sigs(&mut self) {
|
||||
fn visit_coroutine_interior(&mut self) {
|
||||
let fcx_typeck_results = self.fcx.typeck_results.borrow();
|
||||
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
||||
self.tcx().with_stable_hashing_context(move |ref hcx| {
|
||||
for (&expr_def_id, predicates) in
|
||||
fcx_typeck_results.coroutine_stalled_predicates.to_sorted(hcx, false).into_iter()
|
||||
{
|
||||
let predicates =
|
||||
self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id));
|
||||
self.typeck_results.coroutine_stalled_predicates.insert(expr_def_id, predicates);
|
||||
}
|
||||
})
|
||||
for (predicate, cause) in &fcx_typeck_results.coroutine_stalled_predicates {
|
||||
let (predicate, cause) = self.resolve((*predicate, cause.clone()), &cause.span);
|
||||
self.typeck_results.coroutine_stalled_predicates.insert((predicate, cause));
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
@ -759,7 +759,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
|
||||
tcx.hir().par_body_owners(|def_id| {
|
||||
if tcx.is_coroutine(def_id.to_def_id()) {
|
||||
tcx.ensure().mir_coroutine_witnesses(def_id);
|
||||
tcx.ensure().check_coroutine_obligations(def_id);
|
||||
tcx.ensure().check_coroutine_obligations(
|
||||
tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(),
|
||||
);
|
||||
}
|
||||
});
|
||||
sess.time("layout_testing", || layout_test::test_layout(tcx));
|
||||
|
@ -7,10 +7,8 @@
|
||||
GenericArgs, GenericArgsRef, Ty, UserArgs,
|
||||
},
|
||||
};
|
||||
use rustc_data_structures::{
|
||||
fx::FxIndexMap,
|
||||
unord::{ExtendUnord, UnordItems, UnordSet},
|
||||
};
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::{
|
||||
self as hir,
|
||||
@ -201,8 +199,7 @@ pub struct TypeckResults<'tcx> {
|
||||
|
||||
/// Stores the predicates that apply on coroutine witness types.
|
||||
/// formatting modified file tests/ui/coroutine/retain-resume-ref.rs
|
||||
pub coroutine_stalled_predicates:
|
||||
LocalDefIdMap<Vec<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>>,
|
||||
pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>,
|
||||
|
||||
/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
|
||||
/// as `&[u8]`, depending on the pattern in which they are used.
|
||||
|
@ -80,6 +80,10 @@
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_trait_selection::infer::TyCtxtInferExt as _;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
|
||||
use std::{iter, ops};
|
||||
|
||||
pub struct StateTransform;
|
||||
@ -1584,10 +1588,46 @@ pub(crate) fn mir_coroutine_witnesses<'tcx>(
|
||||
let (_, coroutine_layout, _) = compute_layout(liveness_info, body);
|
||||
|
||||
check_suspend_tys(tcx, &coroutine_layout, body);
|
||||
check_field_tys_sized(tcx, &coroutine_layout, def_id);
|
||||
|
||||
Some(coroutine_layout)
|
||||
}
|
||||
|
||||
fn check_field_tys_sized<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
coroutine_layout: &CoroutineLayout<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) {
|
||||
// No need to check if unsized_locals/unsized_fn_params is disabled,
|
||||
// since we will error during typeck.
|
||||
if !tcx.features().unsized_locals && !tcx.features().unsized_fn_params {
|
||||
return;
|
||||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().ignoring_regions().build();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
for field_ty in &coroutine_layout.field_tys {
|
||||
ocx.register_bound(
|
||||
ObligationCause::new(
|
||||
field_ty.source_info.span,
|
||||
def_id,
|
||||
ObligationCauseCode::SizedCoroutineInterior(def_id),
|
||||
),
|
||||
param_env,
|
||||
field_ty.ty,
|
||||
tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
|
||||
);
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let Some(old_yield_ty) = body.yield_ty() else {
|
||||
|
@ -6,18 +6,18 @@
|
||||
|
||||
struct NonClone;
|
||||
|
||||
fn main() {
|
||||
fn test1() {
|
||||
let copyable: u32 = 123;
|
||||
let clonable_0: Vec<u32> = Vec::new();
|
||||
let clonable_1: Vec<u32> = Vec::new();
|
||||
let non_clonable: NonClone = NonClone;
|
||||
|
||||
let gen_copy_0 = move || {
|
||||
yield;
|
||||
drop(copyable);
|
||||
};
|
||||
check_copy(&gen_copy_0);
|
||||
check_clone(&gen_copy_0);
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
let copyable: u32 = 123;
|
||||
let gen_copy_1 = move || {
|
||||
/*
|
||||
let v = vec!['a'];
|
||||
@ -33,6 +33,10 @@ fn main() {
|
||||
};
|
||||
check_copy(&gen_copy_1);
|
||||
check_clone(&gen_copy_1);
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
let clonable_0: Vec<u32> = Vec::new();
|
||||
let gen_clone_0 = move || {
|
||||
let v = vec!['a'];
|
||||
yield;
|
||||
@ -43,6 +47,10 @@ fn main() {
|
||||
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
|
||||
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
|
||||
check_clone(&gen_clone_0);
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
let clonable_1: Vec<u32> = Vec::new();
|
||||
let gen_clone_1 = move || {
|
||||
let v = vec!['a'];
|
||||
/*
|
||||
@ -59,6 +67,10 @@ fn main() {
|
||||
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
|
||||
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
|
||||
check_clone(&gen_clone_1);
|
||||
}
|
||||
|
||||
fn test5() {
|
||||
let non_clonable: NonClone = NonClone;
|
||||
let gen_non_clone = move || {
|
||||
yield;
|
||||
drop(non_clonable);
|
||||
@ -71,3 +83,5 @@ fn main() {
|
||||
|
||||
fn check_copy<T: Copy>(_x: &T) {}
|
||||
fn check_clone<T: Clone>(_x: &T) {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,104 +1,104 @@
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
|
||||
--> $DIR/clone-impl.rs:42:5
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
|
||||
--> $DIR/clone-impl.rs:46:5
|
||||
|
|
||||
LL | let gen_clone_0 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}: Copy`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:40:14
|
||||
--> $DIR/clone-impl.rs:44:14
|
||||
|
|
||||
LL | drop(clonable_0);
|
||||
| ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:72:18
|
||||
--> $DIR/clone-impl.rs:84:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
|
||||
--> $DIR/clone-impl.rs:42:5
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
|
||||
--> $DIR/clone-impl.rs:46:5
|
||||
|
|
||||
LL | let gen_clone_0 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}: Copy`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:38:9
|
||||
--> $DIR/clone-impl.rs:42:9
|
||||
|
|
||||
LL | let v = vec!['a'];
|
||||
| - has type `Vec<char>` which does not implement `Copy`
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `v` maybe used later
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:72:18
|
||||
--> $DIR/clone-impl.rs:84:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
|
||||
--> $DIR/clone-impl.rs:58:5
|
||||
|
|
||||
LL | let gen_clone_1 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}: Copy`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:56:14
|
||||
|
|
||||
LL | drop(clonable_1);
|
||||
| ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
|
||||
--> $DIR/clone-impl.rs:58:5
|
||||
|
|
||||
LL | let gen_clone_1 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}: Copy`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:52:9
|
||||
|
|
||||
LL | let v = vec!['a'];
|
||||
| - has type `Vec<char>` which does not implement `Copy`
|
||||
...
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `v` maybe used later
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:72:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
|
||||
error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
|
||||
--> $DIR/clone-impl.rs:66:5
|
||||
|
|
||||
LL | let gen_non_clone = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
|
||||
LL | let gen_clone_1 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
|
||||
...
|
||||
LL | check_copy(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}: Copy`
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec<u32>`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:64:14
|
||||
|
|
||||
LL | drop(clonable_1);
|
||||
| ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:84:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
|
||||
--> $DIR/clone-impl.rs:66:5
|
||||
|
|
||||
LL | let gen_clone_1 = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`
|
||||
...
|
||||
LL | check_copy(&gen_clone_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec<char>`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy`
|
||||
|
|
||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||
--> $DIR/clone-impl.rs:60:9
|
||||
|
|
||||
LL | let v = vec!['a'];
|
||||
| - has type `Vec<char>` which does not implement `Copy`
|
||||
...
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `v` maybe used later
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:84:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
|
||||
--> $DIR/clone-impl.rs:78:5
|
||||
|
|
||||
LL | let gen_non_clone = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
|
||||
...
|
||||
LL | check_copy(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Copy`
|
||||
|
|
||||
note: captured value does not implement `Copy`
|
||||
--> $DIR/clone-impl.rs:76:14
|
||||
|
|
||||
LL | drop(non_clonable);
|
||||
| ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy`
|
||||
note: required by a bound in `check_copy`
|
||||
--> $DIR/clone-impl.rs:72:18
|
||||
--> $DIR/clone-impl.rs:84:18
|
||||
|
|
||||
LL | fn check_copy<T: Copy>(_x: &T) {}
|
||||
| ^^^^ required by this bound in `check_copy`
|
||||
@ -108,22 +108,22 @@ LL + #[derive(Copy)]
|
||||
LL | struct NonClone;
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
|
||||
--> $DIR/clone-impl.rs:68:5
|
||||
error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
|
||||
--> $DIR/clone-impl.rs:80:5
|
||||
|
|
||||
LL | let gen_non_clone = move || {
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`
|
||||
| ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`
|
||||
...
|
||||
LL | check_clone(&gen_non_clone);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}: Clone`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Clone`
|
||||
|
|
||||
note: captured value does not implement `Clone`
|
||||
--> $DIR/clone-impl.rs:64:14
|
||||
--> $DIR/clone-impl.rs:76:14
|
||||
|
|
||||
LL | drop(non_clonable);
|
||||
| ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone`
|
||||
note: required by a bound in `check_clone`
|
||||
--> $DIR/clone-impl.rs:73:19
|
||||
--> $DIR/clone-impl.rs:85:19
|
||||
|
|
||||
LL | fn check_clone<T: Clone>(_x: &T) {}
|
||||
| ^^^^^ required by this bound in `check_clone`
|
||||
|
Loading…
Reference in New Issue
Block a user