refactor compute_goal_fast_path: turn into a single match
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 1576265..e9c6878 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -13,7 +13,7 @@
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::Certainty;
 use rustc_middle::ty::{
-    self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
+    self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt, TypingMode,
 };
 use rustc_span::{DUMMY_SP, Span};
 
@@ -73,51 +73,60 @@ fn compute_goal_fast_path(
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
         span: Span,
     ) -> Option<Certainty> {
-        if let Some(trait_pred) = goal.predicate.as_trait_clause() {
-            if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
+        let pred = goal.predicate.kind();
+        match pred.skip_binder() {
+            ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
+                let trait_pred = pred.rebind(trait_pred);
+
+                if self.shallow_resolve(trait_pred.self_ty().skip_binder()).is_ty_var()
                 // We don't do this fast path when opaques are defined since we may
                 // eventually use opaques to incompletely guide inference via ty var
                 // self types.
                 // FIXME: Properly consider opaques here.
                 && self.known_no_opaque_types_in_storage()
-            {
-                return Some(Certainty::AMBIGUOUS);
-            }
-
-            if trait_pred.polarity() == ty::PredicatePolarity::Positive {
-                match self.0.tcx.as_lang_item(trait_pred.def_id()) {
-                    Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
-                        let predicate = self.resolve_vars_if_possible(goal.predicate);
-                        if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
-                            return Some(Certainty::Yes);
+                {
+                    Some(Certainty::AMBIGUOUS)
+                } else if trait_pred.polarity() == ty::PredicatePolarity::Positive {
+                    match self.0.tcx.as_lang_item(trait_pred.def_id()) {
+                        Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
+                            let predicate = self.resolve_vars_if_possible(goal.predicate);
+                            if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
+                                return Some(Certainty::Yes);
+                            } else {
+                                None
+                            }
                         }
-                    }
-                    Some(LangItem::Copy | LangItem::Clone) => {
-                        let self_ty =
-                            self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder());
-                        // Unlike `Sized` traits, which always prefer the built-in impl,
-                        // `Copy`/`Clone` may be shadowed by a param-env candidate which
-                        // could force a lifetime error or guide inference. While that's
-                        // not generally desirable, it is observable, so for now let's
-                        // ignore this fast path for types that have regions or infer.
-                        if !self_ty
-                            .has_type_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_INFER)
-                            && self_ty.is_trivially_pure_clone_copy()
-                        {
-                            return Some(Certainty::Yes);
+                        Some(LangItem::Copy | LangItem::Clone) => {
+                            let self_ty =
+                                self.resolve_vars_if_possible(trait_pred.self_ty().skip_binder());
+                            // Unlike `Sized` traits, which always prefer the built-in impl,
+                            // `Copy`/`Clone` may be shadowed by a param-env candidate which
+                            // could force a lifetime error or guide inference. While that's
+                            // not generally desirable, it is observable, so for now let's
+                            // ignore this fast path for types that have regions or infer.
+                            if !self_ty
+                                .has_type_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_INFER)
+                                && self_ty.is_trivially_pure_clone_copy()
+                            {
+                                return Some(Certainty::Yes);
+                            } else {
+                                None
+                            }
                         }
+                        _ => None,
                     }
-                    _ => {}
+                } else {
+                    None
                 }
             }
-        }
-
-        let pred = goal.predicate.kind();
-        match pred.no_bound_vars()? {
             ty::PredicateKind::DynCompatible(def_id) if self.0.tcx.is_dyn_compatible(def_id) => {
                 Some(Certainty::Yes)
             }
             ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(outlives)) => {
+                if outlives.has_escaping_bound_vars() {
+                    return None;
+                }
+
                 self.0.sub_regions(
                     SubregionOrigin::RelateRegionParamBound(span, None),
                     outlives.1,
@@ -127,6 +136,10 @@ fn compute_goal_fast_path(
                 Some(Certainty::Yes)
             }
             ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
+                if outlives.has_escaping_bound_vars() {
+                    return None;
+                }
+
                 self.0.register_type_outlives_constraint(
                     outlives.0,
                     outlives.1,
@@ -137,6 +150,10 @@ fn compute_goal_fast_path(
             }
             ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, .. })
             | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
+                if a.has_escaping_bound_vars() || b.has_escaping_bound_vars() {
+                    return None;
+                }
+
                 match (self.shallow_resolve(a).kind(), self.shallow_resolve(b).kind()) {
                     (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
                         self.sub_unify_ty_vids_raw(a_vid, b_vid);
@@ -146,6 +163,10 @@ fn compute_goal_fast_path(
                 }
             }
             ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) => {
+                if ct.has_escaping_bound_vars() {
+                    return None;
+                }
+
                 if self.shallow_resolve_const(ct).is_ct_infer() {
                     Some(Certainty::AMBIGUOUS)
                 } else {
@@ -153,6 +174,10 @@ fn compute_goal_fast_path(
                 }
             }
             ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
+                if arg.has_escaping_bound_vars() {
+                    return None;
+                }
+
                 let arg = self.shallow_resolve_term(arg);
                 if arg.is_trivially_wf(self.tcx) {
                     Some(Certainty::Yes)