33
44use  rustc_type_ir:: fast_reject:: DeepRejectCtxt ; 
55use  rustc_type_ir:: inherent:: * ; 
6- use  rustc_type_ir:: { self  as  ty,  Interner ,  elaborate} ; 
6+ use  rustc_type_ir:: lang_items:: TraitSolverLangItem ; 
7+ use  rustc_type_ir:: { self  as  ty,  Interner ,  Upcast ,  elaborate} ; 
78use  tracing:: instrument; 
89
910use  super :: assembly:: Candidate ; 
1011use  crate :: delegate:: SolverDelegate ; 
11- use  crate :: solve:: assembly:: { self } ; 
1212use  crate :: solve:: { 
1313    BuiltinImplSource ,  CandidateSource ,  Certainty ,  EvalCtxt ,  Goal ,  GoalSource ,  NoSolution , 
14-     QueryResult , 
14+     QueryResult ,  assembly , 
1515} ; 
1616
1717impl < D ,  I >  assembly:: GoalKind < D >  for  ty:: HostEffectPredicate < I > 
@@ -142,7 +142,7 @@ where
142142            ty:: ImplPolarity :: Positive  => { } 
143143        } ; 
144144
145-         if  !cx. is_const_impl ( impl_def_id)  { 
145+         if  !cx. impl_is_const ( impl_def_id)  { 
146146            return  Err ( NoSolution ) ; 
147147        } 
148148
@@ -204,7 +204,7 @@ where
204204        _ecx :  & mut  EvalCtxt < ' _ ,  D > , 
205205        _goal :  Goal < I ,  Self > , 
206206    )  -> Result < Candidate < I > ,  NoSolution >  { 
207-         todo ! ( "Copy/Clone is not yet const" ) 
207+         Err ( NoSolution ) 
208208    } 
209209
210210    fn  consider_builtin_pointer_like_candidate ( 
@@ -222,11 +222,110 @@ where
222222    } 
223223
224224    fn  consider_builtin_fn_trait_candidates ( 
225-         _ecx :  & mut  EvalCtxt < ' _ ,  D > , 
226-         _goal :  Goal < I ,  Self > , 
225+         ecx :  & mut  EvalCtxt < ' _ ,  D > , 
226+         goal :  Goal < I ,  Self > , 
227227        _kind :  rustc_type_ir:: ClosureKind , 
228228    )  -> Result < Candidate < I > ,  NoSolution >  { 
229-         todo ! ( "Fn* are not yet const" ) 
229+         let  cx = ecx. cx ( ) ; 
230+ 
231+         let  self_ty = goal. predicate . self_ty ( ) ; 
232+         let  ( tupled_inputs_and_output,  def_id,  args)  = match  self_ty. kind ( )  { 
233+             // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. 
234+             ty:: FnDef ( def_id,  args)  => { 
235+                 let  sig = cx. fn_sig ( def_id) ; 
236+                 if  sig. skip_binder ( ) . is_fn_trait_compatible ( ) 
237+                     && !cx. has_target_features ( def_id) 
238+                     && cx. fn_is_const ( def_id) 
239+                 { 
240+                     ( 
241+                         sig. instantiate ( cx,  args) . map_bound ( |sig| { 
242+                             ( Ty :: new_tup ( cx,  sig. inputs ( ) . as_slice ( ) ) ,  sig. output ( ) ) 
243+                         } ) , 
244+                         def_id, 
245+                         args, 
246+                     ) 
247+                 }  else  { 
248+                     return  Err ( NoSolution ) ; 
249+                 } 
250+             } 
251+             // `FnPtr`s are not const for now. 
252+             ty:: FnPtr ( ..)  => { 
253+                 return  Err ( NoSolution ) ; 
254+             } 
255+             // `Closure`s are not const for now. 
256+             ty:: Closure ( ..)  => { 
257+                 return  Err ( NoSolution ) ; 
258+             } 
259+             // `CoroutineClosure`s are not const for now. 
260+             ty:: CoroutineClosure ( ..)  => { 
261+                 return  Err ( NoSolution ) ; 
262+             } 
263+ 
264+             ty:: Bool 
265+             | ty:: Char 
266+             | ty:: Int ( _) 
267+             | ty:: Uint ( _) 
268+             | ty:: Float ( _) 
269+             | ty:: Adt ( _,  _) 
270+             | ty:: Foreign ( _) 
271+             | ty:: Str 
272+             | ty:: Array ( _,  _) 
273+             | ty:: Slice ( _) 
274+             | ty:: RawPtr ( _,  _) 
275+             | ty:: Ref ( _,  _,  _) 
276+             | ty:: Dynamic ( _,  _,  _) 
277+             | ty:: Coroutine ( _,  _) 
278+             | ty:: CoroutineWitness ( ..) 
279+             | ty:: Never 
280+             | ty:: Tuple ( _) 
281+             | ty:: Pat ( _,  _) 
282+             | ty:: Alias ( _,  _) 
283+             | ty:: Param ( _) 
284+             | ty:: Placeholder ( ..) 
285+             | ty:: Infer ( ty:: IntVar ( _)  | ty:: FloatVar ( _) ) 
286+             | ty:: Error ( _)  => return  Err ( NoSolution ) , 
287+ 
288+             ty:: Bound ( ..) 
289+             | ty:: Infer ( ty:: TyVar ( _)  | ty:: FreshTy ( _)  | ty:: FreshIntTy ( _)  | ty:: FreshFloatTy ( _) )  => { 
290+                 panic ! ( "unexpected type `{self_ty:?}`" ) 
291+             } 
292+         } ; 
293+ 
294+         let  output_is_sized_pred = tupled_inputs_and_output. map_bound ( |( _,  output) | { 
295+             ty:: TraitRef :: new ( cx,  cx. require_lang_item ( TraitSolverLangItem :: Sized ) ,  [ output] ) 
296+         } ) ; 
297+         let  requirements = cx
298+             . const_conditions ( def_id) 
299+             . iter_instantiated ( cx,  args) 
300+             . map ( |trait_ref| { 
301+                 ( 
302+                     GoalSource :: ImplWhereBound , 
303+                     goal. with ( cx,  trait_ref. to_host_effect_clause ( cx,  goal. predicate . host ) ) , 
304+                 ) 
305+             } ) 
306+             // A built-in `Fn` impl only holds if the output is sized. 
307+             // (FIXME: technically we only need to check this if the type is a fn ptr...) 
308+             . chain ( [ ( GoalSource :: ImplWhereBound ,  goal. with ( cx,  output_is_sized_pred) ) ] ) ; 
309+ 
310+         let  pred = tupled_inputs_and_output
311+             . map_bound ( |( inputs,  _) | { 
312+                 ty:: ClauseKind :: HostEffect ( ty:: HostEffectPredicate  { 
313+                     trait_ref :  ty:: TraitRef :: new ( cx,  goal. predicate . def_id ( ) ,  [ 
314+                         goal. predicate . self_ty ( ) , 
315+                         inputs, 
316+                     ] ) , 
317+                     host :  goal. predicate . host , 
318+                 } ) 
319+             } ) 
320+             . upcast ( cx) ; 
321+ 
322+         Self :: probe_and_consider_implied_clause ( 
323+             ecx, 
324+             CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Misc ) , 
325+             goal, 
326+             pred, 
327+             requirements, 
328+         ) 
230329    } 
231330
232331    fn  consider_builtin_async_fn_trait_candidates ( 
@@ -311,7 +410,7 @@ where
311410        _ecx :  & mut  EvalCtxt < ' _ ,  D > , 
312411        _goal :  Goal < I ,  Self > , 
313412    )  -> Result < Candidate < I > ,  NoSolution >  { 
314-         unreachable ! ( "Destruct is not const" ) 
413+         Err ( NoSolution ) 
315414    } 
316415
317416    fn  consider_builtin_transmute_candidate ( 
0 commit comments