@@ -44,6 +44,12 @@ pub fn evaluate_host_effect_obligation<'tcx>(
4444 Err ( EvaluationFailure :: NoSolution ) => { }
4545 }
4646
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+
4753 match evaluate_host_effect_from_item_bounds ( selcx, obligation) {
4854 Ok ( result) => return Ok ( result) ,
4955 Err ( EvaluationFailure :: Ambiguous ) => return Err ( EvaluationFailure :: Ambiguous ) ,
@@ -153,7 +159,9 @@ fn evaluate_host_effect_from_bounds<'tcx>(
153159 }
154160}
155161
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 > (
157165 selcx : & mut SelectionContext < ' _ , ' tcx > ,
158166 obligation : & HostEffectObligation < ' tcx > ,
159167) -> Result < ThinVec < PredicateObligation < ' tcx > > , EvaluationFailure > {
@@ -232,6 +240,63 @@ fn evaluate_host_effect_from_item_bounds<'tcx>(
232240 }
233241}
234242
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+
235300fn evaluate_host_effect_from_builtin_impls < ' tcx > (
236301 selcx : & mut SelectionContext < ' _ , ' tcx > ,
237302 obligation : & HostEffectObligation < ' tcx > ,
0 commit comments