1
Fork 0

introduce a Coerce predicate

This commit is contained in:
Niko Matsakis 2020-11-21 07:06:16 -05:00 committed by Mark Rousskov
parent 5a8edc0b76
commit 947c0de028
24 changed files with 153 additions and 2 deletions

View file

@ -969,6 +969,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
);
}
/// Processes a `Coerce` predicate from the fulfillment context.
/// This is NOT the preferred way to handle coercion, which is to
/// invoke `FnCtxt::coerce` or a similar method (see `coercion.rs`).
///
/// This method here is actually a fallback that winds up being
/// invoked when `FnCtxt::coerce` encounters unresolved type variables
/// and records a coercion predicate. Presently, this method is equivalent
/// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up
/// actually requiring `a <: b`. This is of course a valid coercion,
/// but it's not as flexible as `FnCtxt::coerce` would be.
///
/// (We may refactor this in the future, but there are a number of
/// practical obstacles. Among other things, `FnCtxt::coerce` presently
/// records adjustments that are required on the HIR in order to perform
/// the coercion, and we don't currently have a way to manage that.)
pub fn coerce_predicate(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: ty::PolyCoercePredicate<'tcx>,
) -> Option<InferResult<'tcx, ()>> {
let subtype_predicate = predicate.map_bound(|p| ty::SubtypePredicate {
a_is_expected: false, // when coercing from `a` to `b`, `b` is expected
a: p.a,
b: p.b,
});
self.subtype_predicate(cause, param_env, subtype_predicate)
}
pub fn subtype_predicate(
&self,
cause: &ObligationCause<'tcx>,

View file

@ -19,6 +19,7 @@ pub fn explicit_outlives_bounds<'tcx>(
.filter_map(move |kind| match kind {
ty::PredicateKind::Projection(..)
| ty::PredicateKind::Trait(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)

View file

@ -158,6 +158,10 @@ impl Elaborator<'tcx> {
// Currently, we do not "elaborate" predicates like `X <: Y`,
// though conceivably we might.
}
ty::PredicateKind::Coerce(..) => {
// Currently, we do not "elaborate" predicates like `X -> Y`,
// though conceivably we might.
}
ty::PredicateKind::Projection(..) => {
// Nothing to elaborate in a projection predicate.
}