@@ -26,7 +26,9 @@ use rustc_infer::traits::query::NoSolution;
26
26
use rustc_infer:: traits:: Obligation ;
27
27
use rustc_middle:: infer:: canonical:: Certainty as OldCertainty ;
28
28
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
29
- use rustc_middle:: ty:: { RegionOutlivesPredicate , ToPredicate , TypeOutlivesPredicate } ;
29
+ use rustc_middle:: ty:: {
30
+ RegionOutlivesPredicate , SubtypePredicate , ToPredicate , TypeOutlivesPredicate ,
31
+ } ;
30
32
use rustc_span:: DUMMY_SP ;
31
33
32
34
use crate :: traits:: ObligationCause ;
@@ -243,16 +245,34 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
243
245
ty:: PredicateKind :: Clause ( ty:: Clause :: RegionOutlives ( predicate) ) => {
244
246
self . compute_region_outlives_goal ( Goal { param_env, predicate } )
245
247
}
248
+ ty:: PredicateKind :: Subtype ( predicate) => {
249
+ self . compute_subtype_goal ( Goal { param_env, predicate } )
250
+ }
251
+ ty:: PredicateKind :: Coerce ( predicate) => self . compute_subtype_goal ( Goal {
252
+ param_env,
253
+ predicate : SubtypePredicate {
254
+ a_is_expected : true ,
255
+ a : predicate. a ,
256
+ b : predicate. b ,
257
+ } ,
258
+ } ) ,
259
+ ty:: PredicateKind :: ClosureKind ( _, substs, kind) => self . compute_closure_kind_goal (
260
+ substs. as_closure ( ) . kind_ty ( ) . to_opt_closure_kind ( ) ,
261
+ kind,
262
+ ) ,
263
+ ty:: PredicateKind :: Ambiguous => {
264
+ self . make_canonical_response ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) )
265
+ }
246
266
// FIXME: implement these predicates :)
247
267
ty:: PredicateKind :: WellFormed ( _)
248
268
| ty:: PredicateKind :: ObjectSafe ( _)
249
- | ty:: PredicateKind :: ClosureKind ( _, _, _)
250
- | ty:: PredicateKind :: Subtype ( _)
251
- | ty:: PredicateKind :: Coerce ( _)
252
269
| ty:: PredicateKind :: ConstEvaluatable ( _)
253
- | ty:: PredicateKind :: ConstEquate ( _, _)
254
- | ty:: PredicateKind :: TypeWellFormedFromEnv ( _)
255
- | ty:: PredicateKind :: Ambiguous => self . make_canonical_response ( Certainty :: Yes ) ,
270
+ | ty:: PredicateKind :: ConstEquate ( _, _) => {
271
+ self . make_canonical_response ( Certainty :: Yes )
272
+ }
273
+ ty:: PredicateKind :: TypeWellFormedFromEnv ( ..) => {
274
+ bug ! ( "TypeWellFormedFromEnv is only used for Chalk" )
275
+ }
256
276
}
257
277
} else {
258
278
let kind = self . infcx . replace_bound_vars_with_placeholders ( kind) ;
@@ -275,6 +295,36 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
275
295
) -> QueryResult < ' tcx > {
276
296
self . make_canonical_response ( Certainty :: Yes )
277
297
}
298
+
299
+ fn compute_subtype_goal (
300
+ & mut self ,
301
+ goal : Goal < ' tcx , SubtypePredicate < ' tcx > > ,
302
+ ) -> QueryResult < ' tcx > {
303
+ self . infcx . probe ( |_| {
304
+ let InferOk { value : ( ) , obligations } = self
305
+ . infcx
306
+ . at ( & ObligationCause :: dummy ( ) , goal. param_env )
307
+ . sub ( goal. predicate . a , goal. predicate . b ) ?;
308
+ self . evaluate_all_and_make_canonical_response (
309
+ obligations. into_iter ( ) . map ( |pred| pred. into ( ) ) . collect ( ) ,
310
+ )
311
+ } )
312
+ }
313
+
314
+ fn compute_closure_kind_goal (
315
+ & mut self ,
316
+ found_kind : Option < ty:: ClosureKind > ,
317
+ expected_kind : ty:: ClosureKind ,
318
+ ) -> QueryResult < ' tcx > {
319
+ let Some ( found_kind) = found_kind else {
320
+ return self . make_canonical_response ( Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ;
321
+ } ;
322
+ if found_kind. extends ( expected_kind) {
323
+ self . make_canonical_response ( Certainty :: Yes )
324
+ } else {
325
+ Err ( NoSolution )
326
+ }
327
+ }
278
328
}
279
329
280
330
impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
0 commit comments