Skip to content

Commit d6a411c

Browse files
Implement some more predicates
1 parent 2489889 commit d6a411c

File tree

1 file changed

+57
-7
lines changed
  • compiler/rustc_trait_selection/src/solve

1 file changed

+57
-7
lines changed

compiler/rustc_trait_selection/src/solve/mod.rs

+57-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ use rustc_infer::traits::query::NoSolution;
2626
use rustc_infer::traits::Obligation;
2727
use rustc_middle::infer::canonical::Certainty as OldCertainty;
2828
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+
};
3032
use rustc_span::DUMMY_SP;
3133

3234
use crate::traits::ObligationCause;
@@ -243,16 +245,34 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
243245
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(predicate)) => {
244246
self.compute_region_outlives_goal(Goal { param_env, predicate })
245247
}
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+
}
246266
// FIXME: implement these predicates :)
247267
ty::PredicateKind::WellFormed(_)
248268
| ty::PredicateKind::ObjectSafe(_)
249-
| ty::PredicateKind::ClosureKind(_, _, _)
250-
| ty::PredicateKind::Subtype(_)
251-
| ty::PredicateKind::Coerce(_)
252269
| 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+
}
256276
}
257277
} else {
258278
let kind = self.infcx.replace_bound_vars_with_placeholders(kind);
@@ -275,6 +295,36 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
275295
) -> QueryResult<'tcx> {
276296
self.make_canonical_response(Certainty::Yes)
277297
}
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+
}
278328
}
279329

280330
impl<'tcx> EvalCtxt<'_, 'tcx> {

0 commit comments

Comments
 (0)