diff options
| author | Michael Goulet <michael@errs.io> | 2024-04-15 19:44:23 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-04-15 19:44:58 -0400 |
| commit | d29178c2efe7846fdb8c442219d7b70ae83e18e7 (patch) | |
| tree | 89387e3ffde26939db648f1d631aedad80fa3b66 | |
| parent | aa1653e5be13cdcb818ae1f933bec7ad15e33b70 (diff) | |
| download | rust-d29178c2efe7846fdb8c442219d7b70ae83e18e7.tar.gz rust-d29178c2efe7846fdb8c442219d7b70ae83e18e7.zip | |
Do check_coroutine_obligations once per typeck root
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/writeback.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/typeck_results.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine.rs | 40 | ||||
| -rw-r--r-- | tests/ui/coroutine/clone-impl.rs | 24 | ||||
| -rw-r--r-- | tests/ui/coroutine/clone-impl.stderr | 72 |
8 files changed, 118 insertions, 99 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ae3623aa329..cb0ed68edff 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -10,10 +10,9 @@ use rustc_hir as hir; 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_target::abi::FieldIdx; 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 opaque_type_cycle_error( 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); - } - - 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 ocx = ObligationCtxt::new(&infcx); + for (predicate, cause) in &typeck_results.coroutine_stalled_predicates { + ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate)); } - 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)); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 1024dec1d9f..14e4236ad78 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -575,12 +575,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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); } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 73613923e69..fa2bbc3dbd3 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -550,15 +550,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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")] diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 91cef02c7d1..b593c41a8ea 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -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)); diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index aa905466fbc..904d56c516d 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -7,10 +7,8 @@ use crate::{ 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. diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index e2a911f0dc7..b745d97567d 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -80,6 +80,10 @@ use rustc_span::symbol::sym; 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 { diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs index eed6f851bd0..fffdae632ef 100644 --- a/tests/ui/coroutine/clone-impl.rs +++ b/tests/ui/coroutine/clone-impl.rs @@ -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() {} diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr index 1d4804501d8..b454846faac 100644 --- a/tests/ui/coroutine/clone-impl.stderr +++ b/tests/ui/coroutine/clone-impl.stderr @@ -1,76 +1,76 @@ -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 +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_clone_1 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54: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` + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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:56: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: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:46:23: 46:30}` - --> $DIR/clone-impl.rs:58:5 +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:46:23: 46:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54: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` + | ^^^^^^^^^^^^^^^^^^^^^^^^ 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:52:9 + --> $DIR/clone-impl.rs:60:9 | LL | let v = vec!['a']; | - has type `Vec<char>` which does not implement `Copy` @@ -78,27 +78,27 @@ LL | let v = vec!['a']; 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 `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}` - --> $DIR/clone-impl.rs:66:5 +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:62:25: 62:32}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` ... 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` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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:64:14 + --> $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` |
