@@ -8,7 +8,7 @@ use rustc_middle::span_bug;
88use rustc_middle:: traits:: query:: NoSolution ;
99use rustc_middle:: ty:: elaborate:: elaborate;
1010use rustc_middle:: ty:: fast_reject:: DeepRejectCtxt ;
11- use rustc_middle:: ty:: { self , TypingMode } ;
11+ use rustc_middle:: ty:: { self , Ty , TypingMode } ;
1212use thin_vec:: { ThinVec , thin_vec} ;
1313
1414use super :: SelectionContext ;
@@ -303,6 +303,9 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>(
303303 obligation : & HostEffectObligation < ' tcx > ,
304304) -> Result < ThinVec < PredicateObligation < ' tcx > > , EvaluationFailure > {
305305 match selcx. tcx ( ) . as_lang_item ( obligation. predicate . def_id ( ) ) {
306+ Some ( LangItem :: Copy | LangItem :: Clone ) => {
307+ evaluate_host_effect_for_copy_clone_goal ( selcx, obligation)
308+ }
306309 Some ( LangItem :: Destruct ) => evaluate_host_effect_for_destruct_goal ( selcx, obligation) ,
307310 Some ( LangItem :: Fn | LangItem :: FnMut | LangItem :: FnOnce ) => {
308311 evaluate_host_effect_for_fn_goal ( selcx, obligation)
@@ -311,6 +314,95 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>(
311314 }
312315}
313316
317+ fn evaluate_host_effect_for_copy_clone_goal < ' tcx > (
318+ selcx : & mut SelectionContext < ' _ , ' tcx > ,
319+ obligation : & HostEffectObligation < ' tcx > ,
320+ ) -> Result < ThinVec < PredicateObligation < ' tcx > > , EvaluationFailure > {
321+ let tcx = selcx. tcx ( ) ;
322+ let self_ty = obligation. predicate . self_ty ( ) ;
323+ let constituent_tys = match * self_ty. kind ( ) {
324+ // impl Copy/Clone for FnDef, FnPtr
325+ ty:: FnDef ( ..) | ty:: FnPtr ( ..) | ty:: Error ( _) => Ok ( ty:: Binder :: dummy ( vec ! [ ] ) ) ,
326+
327+ // Implementations are provided in core
328+ ty:: Uint ( _)
329+ | ty:: Int ( _)
330+ | ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
331+ | ty:: Bool
332+ | ty:: Float ( _)
333+ | ty:: Char
334+ | ty:: RawPtr ( ..)
335+ | ty:: Never
336+ | ty:: Ref ( _, _, ty:: Mutability :: Not )
337+ | ty:: Array ( ..) => Err ( EvaluationFailure :: NoSolution ) ,
338+
339+ // Cannot implement in core, as we can't be generic over patterns yet,
340+ // so we'd have to list all patterns and type combinations.
341+ ty:: Pat ( ty, ..) => Ok ( ty:: Binder :: dummy ( vec ! [ ty] ) ) ,
342+
343+ ty:: Dynamic ( ..)
344+ | ty:: Str
345+ | ty:: Slice ( _)
346+ | ty:: Foreign ( ..)
347+ | ty:: Ref ( _, _, ty:: Mutability :: Mut )
348+ | ty:: Adt ( _, _)
349+ | ty:: Alias ( _, _)
350+ | ty:: Param ( _)
351+ | ty:: Placeholder ( ..) => Err ( EvaluationFailure :: NoSolution ) ,
352+
353+ ty:: Bound ( ..)
354+ | ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
355+ panic ! ( "unexpected type `{self_ty:?}`" )
356+ }
357+
358+ // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
359+ ty:: Tuple ( tys) => Ok ( ty:: Binder :: dummy ( tys. to_vec ( ) ) ) ,
360+
361+ // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
362+ ty:: Closure ( _, args) => Ok ( ty:: Binder :: dummy ( vec ! [ args. as_closure( ) . tupled_upvars_ty( ) ] ) ) ,
363+
364+ // impl Copy/Clone for CoroutineClosure where Self::TupledUpvars: Copy/Clone
365+ ty:: CoroutineClosure ( _, args) => {
366+ Ok ( ty:: Binder :: dummy ( vec ! [ args. as_coroutine_closure( ) . tupled_upvars_ty( ) ] ) )
367+ }
368+
369+ // only when `coroutine_clone` is enabled and the coroutine is movable
370+ // impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses)
371+ ty:: Coroutine ( def_id, args) => match tcx. coroutine_movability ( def_id) {
372+ ty:: Movability :: Static => Err ( EvaluationFailure :: NoSolution ) ,
373+ ty:: Movability :: Movable => {
374+ if tcx. features ( ) . coroutine_clone ( ) {
375+ Ok ( ty:: Binder :: dummy ( vec ! [
376+ args. as_coroutine( ) . tupled_upvars_ty( ) ,
377+ Ty :: new_coroutine_witness_for_coroutine( tcx, def_id, args) ,
378+ ] ) )
379+ } else {
380+ Err ( EvaluationFailure :: NoSolution )
381+ }
382+ }
383+ } ,
384+
385+ ty:: UnsafeBinder ( _) => Err ( EvaluationFailure :: NoSolution ) ,
386+
387+ // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
388+ ty:: CoroutineWitness ( def_id, args) => Ok ( tcx
389+ . coroutine_hidden_types ( def_id)
390+ . instantiate ( tcx, args)
391+ . map_bound ( |bound| bound. types . to_vec ( ) ) ) ,
392+ } ?;
393+
394+ Ok ( constituent_tys
395+ . iter ( )
396+ . map ( |ty| {
397+ obligation. with (
398+ tcx,
399+ ty. map_bound ( |ty| ty:: TraitRef :: new ( tcx, obligation. predicate . def_id ( ) , [ ty] ) )
400+ . to_host_effect_clause ( tcx, obligation. predicate . constness ) ,
401+ )
402+ } )
403+ . collect ( ) )
404+ }
405+
314406// NOTE: Keep this in sync with `const_conditions_for_destruct` in the new solver.
315407fn evaluate_host_effect_for_destruct_goal < ' tcx > (
316408 selcx : & mut SelectionContext < ' _ , ' tcx > ,
0 commit comments