diff options
| author | Trevor Gross <t.gross35@gmail.com> | 2024-07-26 19:03:05 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-26 19:03:05 -0400 |
| commit | bd18f88dabdf4af5de1cfa180596fab3d503a734 (patch) | |
| tree | 5533d5316374f22a8870b66b2a232a61b3850712 /compiler/rustc_trait_selection/src | |
| parent | 86721a4c90531cbf2d8e1c7124b527e30489782b (diff) | |
| parent | 5a9959fd9daa17e77d609f3c2db4d18554484447 (diff) | |
| download | rust-bd18f88dabdf4af5de1cfa180596fab3d503a734.tar.gz rust-bd18f88dabdf4af5de1cfa180596fab3d503a734.zip | |
Rollup merge of #128201 - compiler-errors:closure-clone, r=oli-obk
Implement `Copy`/`Clone` for async closures We can do so in the same cases that regular closures do. For the purposes of cloning, coroutine-closures are actually precisely the same as regular closures, specifically in the aspect that `Clone` impls care about which is the upvars. The only difference b/w coroutine-closures and regular closures is the type that they *return*, but this type has not been *created* yet, so we don't really have a problem. IDK why I didn't add this impl initially -- I went back and forth a bit on the internal representation for coroutine-closures before settling on a design which largely models regular closures. Previous (not published) iterations of coroutine-closures used to be represented as a special (read: cursed) kind of coroutine, which would probably suffer from the pitfalls that coroutines have that oli mentioned below in https://github.com/rust-lang/rust/pull/128201#issuecomment-2251230274. r? oli-obk
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c007cd5314a..699c05466bd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2262,8 +2262,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - // FIXME(async_closures): These are never clone, for now. - ty::CoroutineClosure(_, _) => None, + ty::CoroutineClosure(_, args) => { + // (*) binder moved here + let ty = self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty()); + if let ty::Infer(ty::TyVar(_)) = ty.kind() { + // Not yet resolved. + Ambiguous + } else { + Where( + obligation + .predicate + .rebind(args.as_coroutine_closure().upvar_tys().to_vec()), + ) + } + } + // `Copy` and `Clone` are automatically implemented for an anonymous adt // if all of its fields are `Copy` and `Clone` ty::Adt(adt, args) if adt.is_anonymous() => { |
