@@ -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,100 @@ 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)  => { 
372+  if  selcx. should_stall_coroutine ( def_id)  { 
373+  return  Err ( EvaluationFailure :: Ambiguous ) ; 
374+  } 
375+  match  tcx. coroutine_movability ( def_id)  { 
376+  ty:: Movability :: Static  => Err ( EvaluationFailure :: NoSolution ) , 
377+  ty:: Movability :: Movable  => { 
378+  if  tcx. features ( ) . coroutine_clone ( )  { 
379+  Ok ( ty:: Binder :: dummy ( vec ! [ 
380+  args. as_coroutine( ) . tupled_upvars_ty( ) , 
381+  Ty :: new_coroutine_witness_for_coroutine( tcx,  def_id,  args) , 
382+  ] ) ) 
383+  }  else  { 
384+  Err ( EvaluationFailure :: NoSolution ) 
385+  } 
386+  } 
387+  } 
388+  } 
389+ 
390+  ty:: UnsafeBinder ( _)  => Err ( EvaluationFailure :: NoSolution ) , 
391+ 
392+  // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types 
393+  ty:: CoroutineWitness ( def_id,  args)  => Ok ( tcx
394+  . coroutine_hidden_types ( def_id) 
395+  . instantiate ( tcx,  args) 
396+  . map_bound ( |bound| bound. types . to_vec ( ) ) ) , 
397+  } ?; 
398+ 
399+  Ok ( constituent_tys
400+  . iter ( ) 
401+  . map ( |ty| { 
402+  obligation. with ( 
403+  tcx, 
404+  ty. map_bound ( |ty| ty:: TraitRef :: new ( tcx,  obligation. predicate . def_id ( ) ,  [ ty] ) ) 
405+  . to_host_effect_clause ( tcx,  obligation. predicate . constness ) , 
406+  ) 
407+  } ) 
408+  . collect ( ) ) 
409+ } 
410+ 
314411// NOTE: Keep this in sync with `const_conditions_for_destruct` in the new solver. 
315412fn  evaluate_host_effect_for_destruct_goal < ' tcx > ( 
316413 selcx :  & mut  SelectionContext < ' _ ,  ' tcx > , 
0 commit comments