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