@@ -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