mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-18 02:34:37 +00:00
introduce a Coerce predicate
This commit is contained in:
parent
5a8edc0b76
commit
947c0de028
@ -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(
|
pub fn subtype_predicate(
|
||||||
&self,
|
&self,
|
||||||
cause: &ObligationCause<'tcx>,
|
cause: &ObligationCause<'tcx>,
|
||||||
|
@ -19,6 +19,7 @@ pub fn explicit_outlives_bounds<'tcx>(
|
|||||||
.filter_map(move |kind| match kind {
|
.filter_map(move |kind| match kind {
|
||||||
ty::PredicateKind::Projection(..)
|
ty::PredicateKind::Projection(..)
|
||||||
| ty::PredicateKind::Trait(..)
|
| ty::PredicateKind::Trait(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::WellFormed(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
|
@ -158,6 +158,10 @@ impl Elaborator<'tcx> {
|
|||||||
// Currently, we do not "elaborate" predicates like `X <: Y`,
|
// Currently, we do not "elaborate" predicates like `X <: Y`,
|
||||||
// though conceivably we might.
|
// though conceivably we might.
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Coerce(..) => {
|
||||||
|
// Currently, we do not "elaborate" predicates like `X -> Y`,
|
||||||
|
// though conceivably we might.
|
||||||
|
}
|
||||||
ty::PredicateKind::Projection(..) => {
|
ty::PredicateKind::Projection(..) => {
|
||||||
// Nothing to elaborate in a projection predicate.
|
// Nothing to elaborate in a projection predicate.
|
||||||
}
|
}
|
||||||
|
@ -1652,6 +1652,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
|||||||
ObjectSafe(..) |
|
ObjectSafe(..) |
|
||||||
ClosureKind(..) |
|
ClosureKind(..) |
|
||||||
Subtype(..) |
|
Subtype(..) |
|
||||||
|
Coerce(..) |
|
||||||
ConstEvaluatable(..) |
|
ConstEvaluatable(..) |
|
||||||
ConstEquate(..) |
|
ConstEquate(..) |
|
||||||
TypeWellFormedFromEnv(..) => continue,
|
TypeWellFormedFromEnv(..) => continue,
|
||||||
|
@ -231,6 +231,10 @@ impl FlagComputation {
|
|||||||
self.add_ty(a);
|
self.add_ty(a);
|
||||||
self.add_ty(b);
|
self.add_ty(b);
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
|
||||||
|
self.add_ty(a);
|
||||||
|
self.add_ty(b);
|
||||||
|
}
|
||||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
||||||
self.add_projection_ty(projection_ty);
|
self.add_projection_ty(projection_ty);
|
||||||
self.add_ty(ty);
|
self.add_ty(ty);
|
||||||
|
@ -485,8 +485,22 @@ pub enum PredicateKind<'tcx> {
|
|||||||
ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
|
ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
|
||||||
|
|
||||||
/// `T1 <: T2`
|
/// `T1 <: T2`
|
||||||
|
///
|
||||||
|
/// This obligation is created most often when we have two
|
||||||
|
/// unresolved type variables and hence don't have enough
|
||||||
|
/// information to process the subtyping obligation yet.
|
||||||
Subtype(SubtypePredicate<'tcx>),
|
Subtype(SubtypePredicate<'tcx>),
|
||||||
|
|
||||||
|
/// `T1` coerced to `T2`
|
||||||
|
///
|
||||||
|
/// Like a subtyping obligation, this is created most often
|
||||||
|
/// when we have two unresolved type variables and hence
|
||||||
|
/// don't have enough information to process the coercion
|
||||||
|
/// obligation yet. At the moment, we actually process coercions
|
||||||
|
/// very much like subtyping and don't handle the full coercion
|
||||||
|
/// logic.
|
||||||
|
Coerce(CoercePredicate<'tcx>),
|
||||||
|
|
||||||
/// Constant initializer must evaluate successfully.
|
/// Constant initializer must evaluate successfully.
|
||||||
ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
|
ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
|
||||||
|
|
||||||
@ -655,6 +669,9 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'t
|
|||||||
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
|
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
|
||||||
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
|
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
|
||||||
|
|
||||||
|
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
|
||||||
|
/// whether the `a` type is the type that we should label as "expected" when
|
||||||
|
/// presenting user diagnostics.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
|
||||||
#[derive(HashStable, TypeFoldable)]
|
#[derive(HashStable, TypeFoldable)]
|
||||||
pub struct SubtypePredicate<'tcx> {
|
pub struct SubtypePredicate<'tcx> {
|
||||||
@ -664,6 +681,15 @@ pub struct SubtypePredicate<'tcx> {
|
|||||||
}
|
}
|
||||||
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
|
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
|
||||||
|
|
||||||
|
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
|
||||||
|
#[derive(HashStable, TypeFoldable)]
|
||||||
|
pub struct CoercePredicate<'tcx> {
|
||||||
|
pub a: Ty<'tcx>,
|
||||||
|
pub b: Ty<'tcx>,
|
||||||
|
}
|
||||||
|
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
|
||||||
|
|
||||||
/// This kind of predicate has no *direct* correspondent in the
|
/// This kind of predicate has no *direct* correspondent in the
|
||||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||||
///
|
///
|
||||||
@ -806,6 +832,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
}
|
}
|
||||||
PredicateKind::Projection(..)
|
PredicateKind::Projection(..)
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::RegionOutlives(..)
|
| PredicateKind::RegionOutlives(..)
|
||||||
| PredicateKind::WellFormed(..)
|
| PredicateKind::WellFormed(..)
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
@ -824,6 +851,7 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
PredicateKind::Trait(..)
|
PredicateKind::Trait(..)
|
||||||
| PredicateKind::Projection(..)
|
| PredicateKind::Projection(..)
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::RegionOutlives(..)
|
| PredicateKind::RegionOutlives(..)
|
||||||
| PredicateKind::WellFormed(..)
|
| PredicateKind::WellFormed(..)
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
|
@ -2236,6 +2236,10 @@ define_print_and_forward_display! {
|
|||||||
p!(print(self.a), " <: ", print(self.b))
|
p!(print(self.a), " <: ", print(self.b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::CoercePredicate<'tcx> {
|
||||||
|
p!(print(self.a), " -> ", print(self.b))
|
||||||
|
}
|
||||||
|
|
||||||
ty::TraitPredicate<'tcx> {
|
ty::TraitPredicate<'tcx> {
|
||||||
p!(print(self.trait_ref.self_ty()), ": ",
|
p!(print(self.trait_ref.self_ty()), ": ",
|
||||||
print(self.trait_ref.print_only_trait_path()))
|
print(self.trait_ref.print_only_trait_path()))
|
||||||
@ -2268,6 +2272,7 @@ define_print_and_forward_display! {
|
|||||||
p!(print(data))
|
p!(print(data))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
||||||
|
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
|
||||||
ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
|
ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||||
ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
|
ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||||
ty::PredicateKind::Projection(predicate) => p!(print(predicate)),
|
ty::PredicateKind::Projection(predicate) => p!(print(predicate)),
|
||||||
|
@ -179,6 +179,7 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
|
|||||||
match *self {
|
match *self {
|
||||||
ty::PredicateKind::Trait(ref a) => a.fmt(f),
|
ty::PredicateKind::Trait(ref a) => a.fmt(f),
|
||||||
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
|
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
|
||||||
|
ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
|
||||||
ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f),
|
ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f),
|
||||||
ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f),
|
ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f),
|
||||||
ty::PredicateKind::Projection(ref pair) => pair.fmt(f),
|
ty::PredicateKind::Projection(ref pair) => pair.fmt(f),
|
||||||
@ -380,6 +381,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> {
|
||||||
|
type Lifted = ty::CoercePredicate<'tcx>;
|
||||||
|
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::CoercePredicate<'tcx>> {
|
||||||
|
tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
|
impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
|
||||||
type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
|
type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
|
||||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||||
@ -420,6 +428,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
|
|||||||
match self {
|
match self {
|
||||||
ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
|
ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
|
||||||
ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
|
ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
|
||||||
|
ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce),
|
||||||
ty::PredicateKind::RegionOutlives(data) => {
|
ty::PredicateKind::RegionOutlives(data) => {
|
||||||
tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
|
tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
|
||||||
}
|
}
|
||||||
|
@ -420,8 +420,8 @@ impl Checker<'mir, 'tcx> {
|
|||||||
ty::PredicateKind::ClosureKind(..) => {
|
ty::PredicateKind::ClosureKind(..) => {
|
||||||
bug!("closure kind predicate on function: {:#?}", predicate)
|
bug!("closure kind predicate on function: {:#?}", predicate)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(_) => {
|
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
|
||||||
bug!("subtype predicate on function: {:#?}", predicate)
|
bug!("subtype/coerce predicate on function: {:#?}", predicate)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Trait(pred) => {
|
ty::PredicateKind::Trait(pred) => {
|
||||||
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
||||||
|
@ -1119,6 +1119,7 @@ crate fn required_region_bounds(
|
|||||||
ty::PredicateKind::Projection(..)
|
ty::PredicateKind::Projection(..)
|
||||||
| ty::PredicateKind::Trait(..)
|
| ty::PredicateKind::Trait(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::WellFormed(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| 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)
|
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) => {
|
ty::PredicateKind::RegionOutlives(predicate) => {
|
||||||
let predicate = bound_predicate.rebind(predicate);
|
let predicate = bound_predicate.rebind(predicate);
|
||||||
let predicate = self.resolve_vars_if_possible(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::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..) => {
|
||||||
let pred = infcx.replace_bound_vars_with_placeholders(binder);
|
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) => {
|
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||||
match const_evaluatable::is_const_evaluatable(
|
match const_evaluatable::is_const_evaluatable(
|
||||||
self.selcx.infcx(),
|
self.selcx.infcx(),
|
||||||
|
@ -308,6 +308,7 @@ fn predicate_references_self(
|
|||||||
| ty::PredicateKind::RegionOutlives(..)
|
| ty::PredicateKind::RegionOutlives(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
@ -336,6 +337,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(..)
|
ty::PredicateKind::Projection(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::RegionOutlives(..)
|
| ty::PredicateKind::RegionOutlives(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::WellFormed(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| 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(
|
ty::PredicateKind::WellFormed(arg) => match wf::obligations(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
@ -128,6 +128,10 @@ pub fn predicate_obligations<'a, 'tcx>(
|
|||||||
wf.compute(a.into());
|
wf.compute(a.into());
|
||||||
wf.compute(b.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) => {
|
ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||||
let obligations = wf.nominal_obligations(def.did, substs);
|
let obligations = wf.nominal_obligations(def.did, substs);
|
||||||
wf.out.extend(obligations);
|
wf.out.extend(obligations);
|
||||||
|
@ -109,6 +109,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
||||||
};
|
};
|
||||||
@ -193,6 +194,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
|||||||
// some of these in terms of chalk operations.
|
// some of these in terms of chalk operations.
|
||||||
ty::PredicateKind::ClosureKind(..)
|
ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..) => {
|
||||||
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
||||||
@ -592,6 +594,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
|||||||
ty::PredicateKind::ObjectSafe(..)
|
ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
@ -719,6 +722,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
|
@ -99,6 +99,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
|||||||
Some(pred) => match pred {
|
Some(pred) => match pred {
|
||||||
ty::PredicateKind::Trait(..)
|
ty::PredicateKind::Trait(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Projection(..)
|
| ty::PredicateKind::Projection(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
|
@ -65,6 +65,7 @@ fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
||||||
|
@ -812,6 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
|
Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(..) => None,
|
ty::PredicateKind::Subtype(..) => None,
|
||||||
|
ty::PredicateKind::Coerce(..) => None,
|
||||||
ty::PredicateKind::RegionOutlives(..) => None,
|
ty::PredicateKind::RegionOutlives(..) => None,
|
||||||
ty::PredicateKind::TypeOutlives(..) => None,
|
ty::PredicateKind::TypeOutlives(..) => None,
|
||||||
ty::PredicateKind::WellFormed(..) => None,
|
ty::PredicateKind::WellFormed(..) => None,
|
||||||
|
@ -841,6 +841,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Subtype(..)
|
ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Projection(..)
|
| ty::PredicateKind::Projection(..)
|
||||||
| ty::PredicateKind::RegionOutlives(..)
|
| ty::PredicateKind::RegionOutlives(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::WellFormed(..)
|
||||||
|
@ -407,6 +407,7 @@ fn trait_predicate_kind<'tcx>(
|
|||||||
| ty::PredicateKind::Projection(_)
|
| ty::PredicateKind::Projection(_)
|
||||||
| ty::PredicateKind::WellFormed(_)
|
| ty::PredicateKind::WellFormed(_)
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
|
@ -56,6 +56,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
||||||
|
@ -332,6 +332,7 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
|
|||||||
ty::PredicateKind::ConstEvaluatable(..) => None,
|
ty::PredicateKind::ConstEvaluatable(..) => None,
|
||||||
|
|
||||||
ty::PredicateKind::Subtype(..)
|
ty::PredicateKind::Subtype(..)
|
||||||
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::WellFormed(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
|
@ -36,6 +36,9 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv: Option<&Ru
|
|||||||
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
|
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
|
||||||
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
|
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
|
||||||
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
|
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
|
||||||
|
ty::PredicateKind::Coerce(_) => {
|
||||||
|
panic!("coerce predicate on function: {:#?}", predicate)
|
||||||
|
},
|
||||||
ty::PredicateKind::Trait(pred) => {
|
ty::PredicateKind::Trait(pred) => {
|
||||||
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user