3
3
4
4
use rustc_type_ir:: fast_reject:: DeepRejectCtxt ;
5
5
use rustc_type_ir:: inherent:: * ;
6
+ use rustc_type_ir:: lang_items:: TraitSolverLangItem ;
6
7
use rustc_type_ir:: { self as ty, Interner , elaborate} ;
7
8
use tracing:: instrument;
8
9
9
- use super :: assembly:: Candidate ;
10
+ use super :: assembly:: { Candidate , structural_traits } ;
10
11
use crate :: delegate:: SolverDelegate ;
11
- use crate :: solve:: assembly:: { self } ;
12
12
use crate :: solve:: {
13
13
BuiltinImplSource , CandidateSource , Certainty , EvalCtxt , Goal , GoalSource , NoSolution ,
14
- QueryResult ,
14
+ QueryResult , assembly ,
15
15
} ;
16
16
17
17
impl < D , I > assembly:: GoalKind < D > for ty:: HostEffectPredicate < I >
@@ -142,7 +142,7 @@ where
142
142
ty:: ImplPolarity :: Positive => { }
143
143
} ;
144
144
145
- if !cx. is_const_impl ( impl_def_id) {
145
+ if !cx. impl_is_const ( impl_def_id) {
146
146
return Err ( NoSolution ) ;
147
147
}
148
148
@@ -207,7 +207,7 @@ where
207
207
_ecx : & mut EvalCtxt < ' _ , D > ,
208
208
_goal : Goal < I , Self > ,
209
209
) -> Result < Candidate < I > , NoSolution > {
210
- todo ! ( "Copy/Clone is not yet const" )
210
+ Err ( NoSolution )
211
211
}
212
212
213
213
fn consider_builtin_pointer_like_candidate (
@@ -225,11 +225,48 @@ where
225
225
}
226
226
227
227
fn consider_builtin_fn_trait_candidates (
228
- _ecx : & mut EvalCtxt < ' _ , D > ,
229
- _goal : Goal < I , Self > ,
228
+ ecx : & mut EvalCtxt < ' _ , D > ,
229
+ goal : Goal < I , Self > ,
230
230
_kind : rustc_type_ir:: ClosureKind ,
231
231
) -> Result < Candidate < I > , NoSolution > {
232
- todo ! ( "Fn* are not yet const" )
232
+ let cx = ecx. cx ( ) ;
233
+
234
+ let self_ty = goal. predicate . self_ty ( ) ;
235
+ let ( inputs_and_output, def_id, args) =
236
+ structural_traits:: extract_fn_def_from_const_callable ( cx, self_ty) ?;
237
+
238
+ // A built-in `Fn` impl only holds if the output is sized.
239
+ // (FIXME: technically we only need to check this if the type is a fn ptr...)
240
+ let output_is_sized_pred = inputs_and_output. map_bound ( |( _, output) | {
241
+ ty:: TraitRef :: new ( cx, cx. require_lang_item ( TraitSolverLangItem :: Sized ) , [ output] )
242
+ } ) ;
243
+ let requirements = cx
244
+ . const_conditions ( def_id)
245
+ . iter_instantiated ( cx, args)
246
+ . map ( |trait_ref| {
247
+ (
248
+ GoalSource :: ImplWhereBound ,
249
+ goal. with ( cx, trait_ref. to_host_effect_clause ( cx, goal. predicate . constness ) ) ,
250
+ )
251
+ } )
252
+ . chain ( [ ( GoalSource :: ImplWhereBound , goal. with ( cx, output_is_sized_pred) ) ] ) ;
253
+
254
+ let pred = inputs_and_output
255
+ . map_bound ( |( inputs, _) | {
256
+ ty:: TraitRef :: new ( cx, goal. predicate . def_id ( ) , [
257
+ goal. predicate . self_ty ( ) ,
258
+ Ty :: new_tup ( cx, inputs. as_slice ( ) ) ,
259
+ ] )
260
+ } )
261
+ . to_host_effect_clause ( cx, goal. predicate . constness ) ;
262
+
263
+ Self :: probe_and_consider_implied_clause (
264
+ ecx,
265
+ CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Misc ) ,
266
+ goal,
267
+ pred,
268
+ requirements,
269
+ )
233
270
}
234
271
235
272
fn consider_builtin_async_fn_trait_candidates (
@@ -314,7 +351,7 @@ where
314
351
_ecx : & mut EvalCtxt < ' _ , D > ,
315
352
_goal : Goal < I , Self > ,
316
353
) -> Result < Candidate < I > , NoSolution > {
317
- unreachable ! ( "Destruct is not const" )
354
+ Err ( NoSolution )
318
355
}
319
356
320
357
fn consider_builtin_transmute_candidate (
0 commit comments