@@ -44,6 +44,12 @@ pub fn evaluate_host_effect_obligation<'tcx>(
44
44
Err ( EvaluationFailure :: NoSolution ) => { }
45
45
}
46
46
47
+ match evaluate_host_effect_from_conditionally_const_item_bounds ( selcx, obligation) {
48
+ Ok ( result) => return Ok ( result) ,
49
+ Err ( EvaluationFailure :: Ambiguous ) => return Err ( EvaluationFailure :: Ambiguous ) ,
50
+ Err ( EvaluationFailure :: NoSolution ) => { }
51
+ }
52
+
47
53
match evaluate_host_effect_from_item_bounds ( selcx, obligation) {
48
54
Ok ( result) => return Ok ( result) ,
49
55
Err ( EvaluationFailure :: Ambiguous ) => return Err ( EvaluationFailure :: Ambiguous ) ,
@@ -153,7 +159,9 @@ fn evaluate_host_effect_from_bounds<'tcx>(
153
159
}
154
160
}
155
161
156
- fn evaluate_host_effect_from_item_bounds < ' tcx > (
162
+ /// Assembles constness bounds from `~const` item bounds on alias types, which only
163
+ /// hold if the `~const` where bounds also hold and the parent trait is `~const`.
164
+ fn evaluate_host_effect_from_conditionally_const_item_bounds < ' tcx > (
157
165
selcx : & mut SelectionContext < ' _ , ' tcx > ,
158
166
obligation : & HostEffectObligation < ' tcx > ,
159
167
) -> Result < ThinVec < PredicateObligation < ' tcx > > , EvaluationFailure > {
@@ -232,6 +240,63 @@ fn evaluate_host_effect_from_item_bounds<'tcx>(
232
240
}
233
241
}
234
242
243
+ /// Assembles constness bounds "normal" item bounds on aliases, which may include
244
+ /// unconditionally `const` bounds that are *not* conditional and thus always hold.
245
+ fn evaluate_host_effect_from_item_bounds < ' tcx > (
246
+ selcx : & mut SelectionContext < ' _ , ' tcx > ,
247
+ obligation : & HostEffectObligation < ' tcx > ,
248
+ ) -> Result < ThinVec < PredicateObligation < ' tcx > > , EvaluationFailure > {
249
+ let infcx = selcx. infcx ;
250
+ let tcx = infcx. tcx ;
251
+ let drcx = DeepRejectCtxt :: relate_rigid_rigid ( selcx. tcx ( ) ) ;
252
+ let mut candidate = None ;
253
+
254
+ let mut consider_ty = obligation. predicate . self_ty ( ) ;
255
+ while let ty:: Alias ( kind @ ( ty:: Projection | ty:: Opaque ) , alias_ty) = * consider_ty. kind ( ) {
256
+ for clause in tcx. item_bounds ( alias_ty. def_id ) . iter_instantiated ( tcx, alias_ty. args ) {
257
+ let bound_clause = clause. kind ( ) ;
258
+ let ty:: ClauseKind :: HostEffect ( data) = bound_clause. skip_binder ( ) else {
259
+ continue ;
260
+ } ;
261
+ let data = bound_clause. rebind ( data) ;
262
+ if data. skip_binder ( ) . trait_ref . def_id != obligation. predicate . trait_ref . def_id {
263
+ continue ;
264
+ }
265
+
266
+ if !drcx. args_may_unify (
267
+ obligation. predicate . trait_ref . args ,
268
+ data. skip_binder ( ) . trait_ref . args ,
269
+ ) {
270
+ continue ;
271
+ }
272
+
273
+ let is_match =
274
+ infcx. probe ( |_| match_candidate ( selcx, obligation, data, true , |_, _| { } ) . is_ok ( ) ) ;
275
+
276
+ if is_match {
277
+ if candidate. is_some ( ) {
278
+ return Err ( EvaluationFailure :: Ambiguous ) ;
279
+ } else {
280
+ candidate = Some ( data) ;
281
+ }
282
+ }
283
+ }
284
+
285
+ if kind != ty:: Projection {
286
+ break ;
287
+ }
288
+
289
+ consider_ty = alias_ty. self_ty ( ) ;
290
+ }
291
+
292
+ if let Some ( data) = candidate {
293
+ Ok ( match_candidate ( selcx, obligation, data, true , |_, _| { } )
294
+ . expect ( "candidate matched before, so it should match again" ) )
295
+ } else {
296
+ Err ( EvaluationFailure :: NoSolution )
297
+ }
298
+ }
299
+
235
300
fn evaluate_host_effect_from_builtin_impls < ' tcx > (
236
301
selcx : & mut SelectionContext < ' _ , ' tcx > ,
237
302
obligation : & HostEffectObligation < ' tcx > ,
0 commit comments