diff options
Diffstat (limited to 'compiler/rustc_ty_utils/src/instance.rs')
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 9faad10dd14..7fa416197b3 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -209,10 +209,8 @@ fn resolve_associated_item<'tcx>( let name = tcx.item_name(trait_item_id); if name == sym::clone { let self_ty = trait_ref.self_ty(); - - let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env); match self_ty.kind() { - _ if is_copy => (), + ty::FnDef(..) | ty::FnPtr(_) => (), ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Closure(..) @@ -278,6 +276,24 @@ fn resolve_associated_item<'tcx>( def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), args: rcvr_args, }), + ty::CoroutineClosure(coroutine_closure_def_id, args) => { + // When a coroutine-closure implements the `Fn` traits, then it + // always dispatches to the `FnOnce` implementation. This is to + // ensure that the `closure_kind` of the resulting closure is in + // sync with the built-in trait implementations (since all of the + // implementations return `FnOnce::Output`). + if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() { + Some(Instance::new(coroutine_closure_def_id, args)) + } else { + Some(Instance { + def: ty::InstanceDef::ConstructCoroutineInClosureShim { + coroutine_closure_def_id, + target_kind: ty::ClosureKind::FnOnce, + }, + args, + }) + } + } _ => bug!( "no built-in definition for `{trait_ref}::{}` for non-fn type", tcx.item_name(trait_item_id) @@ -306,6 +322,19 @@ fn resolve_associated_item<'tcx>( Some(Instance::new(coroutine_closure_def_id, args)) } } + ty::Closure(closure_def_id, args) => { + let trait_closure_kind = tcx.fn_trait_kind_from_def_id(trait_id).unwrap(); + Some(Instance::resolve_closure( + tcx, + closure_def_id, + args, + trait_closure_kind, + )) + } + ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { + def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_args.type_at(0)), + args: rcvr_args, + }), _ => bug!( "no built-in definition for `{trait_ref}::{}` for non-lending-closure type", tcx.item_name(trait_item_id) |
