introduce a Coerce predicate
This commit is contained in:
parent
5a8edc0b76
commit
947c0de028
24 changed files with 153 additions and 2 deletions
|
@ -1119,6 +1119,7 @@ crate fn required_region_bounds(
|
|||
ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::Trait(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
|
|
|
@ -565,6 +565,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(predicate) => {
|
||||
// Errors for Coerce predicates show up as
|
||||
// `FulfillmentErrorCode::CodeSubtypeError`,
|
||||
// not selection error.
|
||||
span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
|
||||
}
|
||||
|
||||
ty::PredicateKind::RegionOutlives(predicate) => {
|
||||
let predicate = bound_predicate.rebind(predicate);
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
|
|
|
@ -402,6 +402,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
| ty::PredicateKind::ObjectSafe(_)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::Subtype(_)
|
||||
| ty::PredicateKind::Coerce(_)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..) => {
|
||||
let pred = infcx.replace_bound_vars_with_placeholders(binder);
|
||||
|
@ -517,6 +518,31 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(coerce) => {
|
||||
match self.selcx.infcx().coerce_predicate(
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
Binder::dummy(coerce),
|
||||
) {
|
||||
None => {
|
||||
// None means that both are unresolved.
|
||||
pending_obligation.stalled_on = vec![
|
||||
TyOrConstInferVar::maybe_from_ty(coerce.a).unwrap(),
|
||||
TyOrConstInferVar::maybe_from_ty(coerce.b).unwrap(),
|
||||
];
|
||||
ProcessResult::Unchanged
|
||||
}
|
||||
Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
|
||||
Some(Err(err)) => {
|
||||
let expected_found = ExpectedFound::new(false, coerce.a, coerce.b);
|
||||
ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
|
||||
expected_found,
|
||||
err,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
match const_evaluatable::is_const_evaluatable(
|
||||
self.selcx.infcx(),
|
||||
|
|
|
@ -308,6 +308,7 @@ fn predicate_references_self(
|
|||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||
|
@ -336,6 +337,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||
}
|
||||
ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
|
|
|
@ -512,6 +512,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::Coerce(p) => {
|
||||
let p = bound_predicate.rebind(p);
|
||||
// Does this code ever run?
|
||||
match self.infcx.coerce_predicate(&obligation.cause, obligation.param_env, p) {
|
||||
Some(Ok(InferOk { mut obligations, .. })) => {
|
||||
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
|
||||
self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
obligations.into_iter(),
|
||||
)
|
||||
}
|
||||
Some(Err(_)) => Ok(EvaluatedToErr),
|
||||
None => Ok(EvaluatedToAmbig),
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::WellFormed(arg) => match wf::obligations(
|
||||
self.infcx,
|
||||
obligation.param_env,
|
||||
|
|
|
@ -128,6 +128,10 @@ pub fn predicate_obligations<'a, 'tcx>(
|
|||
wf.compute(a.into());
|
||||
wf.compute(b.into());
|
||||
}
|
||||
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
|
||||
wf.compute(a.into());
|
||||
wf.compute(b.into());
|
||||
}
|
||||
ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
let obligations = wf.nominal_obligations(def.did, substs);
|
||||
wf.out.extend(obligations);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue