about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs29
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs1
-rw-r--r--compiler/rustc_infer/src/traits/util.rs4
-rw-r--r--compiler/rustc_lint/src/builtin.rs1
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs28
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs9
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs4
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs4
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs1
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs1
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs1
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs1
-rw-r--r--compiler/rustc_typeck/src/outlives/explicit.rs1
-rw-r--r--src/librustdoc/clean/mod.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs3
24 files changed, 153 insertions, 2 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 26bee3596e3..172eb1f48d7 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -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>,
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 07c75d50d91..4dd5e8ba545 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -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(..)
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 3139e121163..3a25cb66896 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -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.
             }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 77c7040e6a7..5a72db7752d 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1652,6 +1652,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
                     ObjectSafe(..) |
                     ClosureKind(..) |
                     Subtype(..) |
+                    Coerce(..) |
                     ConstEvaluatable(..) |
                     ConstEquate(..) |
                     TypeWellFormedFromEnv(..) => continue,
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 391c8292bd5..04df706d908 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -231,6 +231,10 @@ impl FlagComputation {
                 self.add_ty(a);
                 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 }) => {
                 self.add_projection_ty(projection_ty);
                 self.add_ty(ty);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 0906cffa05c..9fcf35b7320 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -485,8 +485,22 @@ pub enum PredicateKind<'tcx> {
     ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
 
     /// `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>),
 
+    /// `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.
     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 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(HashStable, TypeFoldable)]
 pub struct SubtypePredicate<'tcx> {
@@ -664,6 +681,15 @@ pub struct 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
 /// syntax, but it roughly corresponds to the syntactic forms:
 ///
@@ -806,6 +832,7 @@ impl<'tcx> Predicate<'tcx> {
             }
             PredicateKind::Projection(..)
             | PredicateKind::Subtype(..)
+            | PredicateKind::Coerce(..)
             | PredicateKind::RegionOutlives(..)
             | PredicateKind::WellFormed(..)
             | PredicateKind::ObjectSafe(..)
@@ -824,6 +851,7 @@ impl<'tcx> Predicate<'tcx> {
             PredicateKind::Trait(..)
             | PredicateKind::Projection(..)
             | PredicateKind::Subtype(..)
+            | PredicateKind::Coerce(..)
             | PredicateKind::RegionOutlives(..)
             | PredicateKind::WellFormed(..)
             | PredicateKind::ObjectSafe(..)
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c96621338f5..8558d6bb00e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2236,6 +2236,10 @@ define_print_and_forward_display! {
         p!(print(self.a), " <: ", print(self.b))
     }
 
+    ty::CoercePredicate<'tcx> {
+        p!(print(self.a), " -> ", print(self.b))
+    }
+
     ty::TraitPredicate<'tcx> {
         p!(print(self.trait_ref.self_ty()), ": ",
            print(self.trait_ref.print_only_trait_path()))
@@ -2268,6 +2272,7 @@ define_print_and_forward_display! {
                 p!(print(data))
             }
             ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
+            ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
             ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
             ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
             ty::PredicateKind::Projection(predicate) => p!(print(predicate)),
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 62397752db2..a46cac1e7f7 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -179,6 +179,7 @@ impl fmt::Debug for ty::PredicateKind<'tcx> {
         match *self {
             ty::PredicateKind::Trait(ref a) => a.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::TypeOutlives(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> {
     type Lifted = ty::OutlivesPredicate<A::Lifted, B::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 {
             ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
             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) => {
                 tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
             }
diff --git a/compiler/rustc_mir/src/transform/check_consts/check.rs b/compiler/rustc_mir/src/transform/check_consts/check.rs
index 48fd63b258c..09e908e6757 100644
--- a/compiler/rustc_mir/src/transform/check_consts/check.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/check.rs
@@ -420,8 +420,8 @@ impl Checker<'mir, 'tcx> {
                     ty::PredicateKind::ClosureKind(..) => {
                         bug!("closure kind predicate on function: {:#?}", predicate)
                     }
-                    ty::PredicateKind::Subtype(_) => {
-                        bug!("subtype predicate on function: {:#?}", predicate)
+                    ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
+                        bug!("subtype/coerce predicate on function: {:#?}", predicate)
                     }
                     ty::PredicateKind::Trait(pred) => {
                         if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index 1a195ce18ec..e6686b8cc70 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -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(..)
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 2f91666ca64..2c09c551b65 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -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);
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 7048f0dbedc..a2095907c7a 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -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(),
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 04bc689d511..02b43de0d16 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -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(..)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 38dbacbf2ae..c9bcc44fab6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -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,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 9c9664d7b5e..afef784b4c6 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -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);
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 974755e9e26..330fd497fa1 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -109,6 +109,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                 | ty::PredicateKind::ObjectSafe(..)
                 | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::Subtype(..)
+                | ty::PredicateKind::Coerce(..)
                 | ty::PredicateKind::ConstEvaluatable(..)
                 | 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.
             ty::PredicateKind::ClosureKind(..)
             | ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..) => {
                 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::ClosureKind(..)
             | ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
@@ -719,6 +722,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
             | ty::PredicateKind::ObjectSafe(..)
             | ty::PredicateKind::ClosureKind(..)
             | ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..)
             | ty::PredicateKind::TypeWellFormedFromEnv(..) => {
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 90ba90259c3..1d10d068490 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -99,6 +99,7 @@ fn compute_implied_outlives_bounds<'tcx>(
                 Some(pred) => match pred {
                     ty::PredicateKind::Trait(..)
                     | ty::PredicateKind::Subtype(..)
+                    | ty::PredicateKind::Coerce(..)
                     | ty::PredicateKind::Projection(..)
                     | ty::PredicateKind::ClosureKind(..)
                     | ty::PredicateKind::ObjectSafe(..)
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index 5ad0684fe6e..61ab5e28b67 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -65,6 +65,7 @@ fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
         | ty::PredicateKind::ObjectSafe(..)
         | ty::PredicateKind::ClosureKind(..)
         | ty::PredicateKind::Subtype(..)
+        | ty::PredicateKind::Coerce(..)
         | ty::PredicateKind::ConstEvaluatable(..)
         | ty::PredicateKind::ConstEquate(..)
         | ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 9405b64260c..a9b1fb790ed 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -812,6 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
                     }
                     ty::PredicateKind::Subtype(..) => None,
+                    ty::PredicateKind::Coerce(..) => None,
                     ty::PredicateKind::RegionOutlives(..) => None,
                     ty::PredicateKind::TypeOutlives(..) => None,
                     ty::PredicateKind::WellFormed(..) => None,
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index c6e6c8c5d70..486e4d15d65 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -841,6 +841,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     }
                 }
                 ty::PredicateKind::Subtype(..)
+                | ty::PredicateKind::Coerce(..)
                 | ty::PredicateKind::Projection(..)
                 | ty::PredicateKind::RegionOutlives(..)
                 | ty::PredicateKind::WellFormed(..)
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index d5d81603fc5..e148370a036 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -407,6 +407,7 @@ fn trait_predicate_kind<'tcx>(
         | ty::PredicateKind::Projection(_)
         | ty::PredicateKind::WellFormed(_)
         | ty::PredicateKind::Subtype(_)
+        | ty::PredicateKind::Coerce(_)
         | ty::PredicateKind::ObjectSafe(_)
         | ty::PredicateKind::ClosureKind(..)
         | ty::PredicateKind::ConstEvaluatable(..)
diff --git a/compiler/rustc_typeck/src/outlives/explicit.rs b/compiler/rustc_typeck/src/outlives/explicit.rs
index 6e5be87928d..2ac1a18cffa 100644
--- a/compiler/rustc_typeck/src/outlives/explicit.rs
+++ b/compiler/rustc_typeck/src/outlives/explicit.rs
@@ -56,6 +56,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
                     | ty::PredicateKind::ObjectSafe(..)
                     | ty::PredicateKind::ClosureKind(..)
                     | ty::PredicateKind::Subtype(..)
+                    | ty::PredicateKind::Coerce(..)
                     | ty::PredicateKind::ConstEvaluatable(..)
                     | ty::PredicateKind::ConstEquate(..)
                     | ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 73b5ef0857d..b6ff3890c58 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -332,6 +332,7 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
             ty::PredicateKind::ConstEvaluatable(..) => None,
 
             ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Coerce(..)
             | ty::PredicateKind::WellFormed(..)
             | ty::PredicateKind::ObjectSafe(..)
             | ty::PredicateKind::ClosureKind(..)
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index dee9d487c78..8e544f58066 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -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::ClosureKind(..) => panic!("closure kind 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) => {
                     if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
                         continue;