about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs1
-rw-r--r--compiler/rustc_infer/src/traits/util.rs3
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs5
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs13
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs1
-rw-r--r--compiler/rustc_type_ir/src/predicate_kind.rs24
-rw-r--r--compiler/stable_mir/src/ty.rs1
-rw-r--r--tests/ui/closure_context/issue-26046-fn-mut.stderr16
-rw-r--r--tests/ui/closure_context/issue-26046-fn-once.stderr16
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr16
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr16
-rw-r--r--tests/ui/closures/closure-wrong-kind.stderr14
-rw-r--r--tests/ui/issues/issue-34349.stderr16
-rw-r--r--tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr53
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr15
26 files changed, 76 insertions, 191 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 750ed2c3491..91540e0c284 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -662,7 +662,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // this closure yet; this is exactly why the other
                 // code is looking for a self type of an unresolved
                 // inference variable.
-                | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::Ambiguous
                  => None,
             },
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index ed3409149d0..1bcae736fd9 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -308,9 +308,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
             ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {
                 // Nothing to elaborate in a projection predicate.
             }
-            ty::PredicateKind::ClosureKind(..) => {
-                // Nothing to elaborate when waiting for a closure's kind to be inferred.
-            }
             ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
                 // Currently, we do not elaborate const-evaluatable
                 // predicates.
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 4d7b12662c6..cd9b429ec56 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -263,9 +263,6 @@ impl FlagComputation {
                 self.add_args(slice::from_ref(&arg));
             }
             ty::PredicateKind::ObjectSafe(_def_id) => {}
-            ty::PredicateKind::ClosureKind(_def_id, args, _kind) => {
-                self.add_args(args);
-            }
             ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
                 self.add_const(uv);
             }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 2436daf62cf..bab79bfcae9 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -548,7 +548,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
             | PredicateKind::AliasRelate(..)
             | PredicateKind::ObjectSafe(_)
-            | PredicateKind::ClosureKind(_, _, _)
             | PredicateKind::Subtype(_)
             | PredicateKind::Coerce(_)
             | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
@@ -1276,7 +1275,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
             | PredicateKind::Clause(ClauseKind::WellFormed(..))
             | PredicateKind::ObjectSafe(..)
-            | PredicateKind::ClosureKind(..)
             | PredicateKind::Clause(ClauseKind::TypeOutlives(..))
             | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
             | PredicateKind::ConstEquate(..)
@@ -1296,7 +1294,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
             | PredicateKind::Clause(ClauseKind::WellFormed(..))
             | PredicateKind::ObjectSafe(..)
-            | PredicateKind::ClosureKind(..)
             | PredicateKind::Clause(ClauseKind::TypeOutlives(..))
             | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
             | PredicateKind::ConstEquate(..)
@@ -1317,7 +1314,6 @@ impl<'tcx> Predicate<'tcx> {
             | PredicateKind::Clause(ClauseKind::RegionOutlives(..))
             | PredicateKind::Clause(ClauseKind::WellFormed(..))
             | PredicateKind::ObjectSafe(..)
-            | PredicateKind::ClosureKind(..)
             | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..))
             | PredicateKind::ConstEquate(..)
             | PredicateKind::Ambiguous => None,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d478677c367..bbbd3347361 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2781,11 +2781,6 @@ define_print! {
             ty::PredicateKind::ObjectSafe(trait_def_id) => {
                 p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
             }
-            ty::PredicateKind::ClosureKind(closure_def_id, _closure_args, kind) => p!(
-                "the closure `",
-                print_value_path(closure_def_id, &[]),
-                write("` implements the trait `{}`", kind)
-            ),
             ty::PredicateKind::ConstEquate(c1, c2) => {
                 p!("the constant `", print(c1), "` equals `", print(c2), "`")
             }
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 167a01ab799..9ad4f9800b4 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -1699,13 +1699,6 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
             PredicateKind::ObjectSafe(did) => {
                 stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did))
             }
-            PredicateKind::ClosureKind(did, generic_args, closure_kind) => {
-                stable_mir::ty::PredicateKind::ClosureKind(
-                    tables.closure_def(*did),
-                    generic_args.stable(tables),
-                    closure_kind.stable(tables),
-                )
-            }
             PredicateKind::Subtype(subtype_predicate) => {
                 stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables))
             }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 23ce0a301ce..ded7874b62a 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -406,8 +406,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 ty::PredicateKind::Coerce(predicate) => {
                     self.compute_coerce_goal(Goal { param_env, predicate })
                 }
-                ty::PredicateKind::ClosureKind(def_id, args, kind) => self
-                    .compute_closure_kind_goal(Goal { param_env, predicate: (def_id, args, kind) }),
                 ty::PredicateKind::ObjectSafe(trait_def_id) => {
                     self.compute_object_safe_goal(trait_def_id)
                 }
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index f1d3091225c..b73ec93b824 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -135,7 +135,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                                     }
                                     ty::PredicateKind::Clause(_)
                                     | ty::PredicateKind::ObjectSafe(_)
-                                    | ty::PredicateKind::ClosureKind(_, _, _)
                                     | ty::PredicateKind::Ambiguous => {
                                         FulfillmentErrorCode::CodeSelectionError(
                                             SelectionError::Unimplemented,
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index dbf6749b523..867b1c913ef 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -822,7 +822,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
                 | ty::PredicateKind::AliasRelate(..)
                 | ty::PredicateKind::ObjectSafe(..)
-                | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::Subtype(..)
                 // FIXME(generic_const_exprs): you can absolutely add this as a where clauses
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 5239725f509..5f642ca9a79 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -786,11 +786,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         report_object_safety_error(self.tcx, span, trait_def_id, violations)
                     }
 
-                    ty::PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
-                        let found_kind = self.closure_kind(closure_args).unwrap();
-                        self.report_closure_error(&obligation, closure_def_id, found_kind, kind)
-                    }
-
                     ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
                         let ty = self.resolve_vars_if_possible(ty);
                         match self.tcx.sess.opts.unstable_opts.trait_solver {
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index fb9cf51b513..08544b4a93a 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -350,7 +350,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
                 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
                 | ty::PredicateKind::ObjectSafe(_)
-                | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::Subtype(_)
                 | ty::PredicateKind::Coerce(_)
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
@@ -411,19 +410,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     }
                 }
 
-                ty::PredicateKind::ClosureKind(_, closure_args, kind) => {
-                    match self.selcx.infcx.closure_kind(closure_args) {
-                        Some(closure_kind) => {
-                            if closure_kind.extends(kind) {
-                                ProcessResult::Changed(vec![])
-                            } else {
-                                ProcessResult::Error(CodeSelectionError(Unimplemented))
-                            }
-                        }
-                        None => ProcessResult::Unchanged,
-                    }
-                }
-
                 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
                     match wf::obligations(
                         self.selcx.infcx,
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 57df277f4b3..94d6b15fe43 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -130,7 +130,6 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
                 | ty::PredicateKind::Subtype(..)
                 | ty::PredicateKind::Coerce(..)
                 | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
-                | ty::PredicateKind::ClosureKind(..)
                 | ty::PredicateKind::ObjectSafe(..)
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
                 | ty::PredicateKind::ConstEquate(..)
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 1529f736109..a0ed773b62c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -291,8 +291,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         }
                     }
                     None => {
-                        debug!("assemble_unboxed_candidates: closure_kind not yet known");
-                        candidates.vec.push(ClosureCandidate { is_const });
+                        if kind == ty::ClosureKind::FnOnce {
+                            candidates.vec.push(ClosureCandidate { is_const });
+                        } else {
+                            candidates.ambiguous = true;
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 2ab3ecbd5a3..6cb76addd7d 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -821,11 +821,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         obligation: &PolyTraitObligation<'tcx>,
     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
-        let kind = self
-            .tcx()
-            .fn_trait_kind_from_def_id(obligation.predicate.def_id())
-            .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
-
         // Okay to skip binder because the args on closure types never
         // touch bound regions, they just capture the in-scope
         // type/region parameters.
@@ -835,15 +830,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         };
 
         let trait_ref = self.closure_trait_ref_unnormalized(obligation, args);
-        let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
+        let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
 
         debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
 
-        nested.push(obligation.with(
-            self.tcx(),
-            ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, args, kind)),
-        ));
-
         Ok(nested)
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 1ed0da59b64..4bef3626655 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -885,19 +885,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
                 }
 
-                ty::PredicateKind::ClosureKind(_, closure_args, kind) => {
-                    match self.infcx.closure_kind(closure_args) {
-                        Some(closure_kind) => {
-                            if closure_kind.extends(kind) {
-                                Ok(EvaluatedToOk)
-                            } else {
-                                Ok(EvaluatedToErr)
-                            }
-                        }
-                        None => Ok(EvaluatedToAmbig),
-                    }
-                }
-
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
                     match const_evaluatable::is_const_evaluatable(
                         self.infcx,
diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs
index cb2a36cb998..06486a100a9 100644
--- a/compiler/rustc_traits/src/normalize_erasing_regions.rs
+++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs
@@ -58,7 +58,6 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
         | ty::PredicateKind::AliasRelate(..)
         | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
         | ty::PredicateKind::ObjectSafe(..)
-        | ty::PredicateKind::ClosureKind(..)
         | ty::PredicateKind::Subtype(..)
         | ty::PredicateKind::Coerce(..)
         | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs
index da041ab1f35..f6a2dca4eee 100644
--- a/compiler/rustc_type_ir/src/predicate_kind.rs
+++ b/compiler/rustc_type_ir/src/predicate_kind.rs
@@ -129,11 +129,6 @@ pub enum PredicateKind<I: Interner> {
     /// Trait must be object-safe.
     ObjectSafe(I::DefId),
 
-    /// No direct syntax. May be thought of as `where T: FnFoo<...>`
-    /// for some generic args `...` and `T` being a closure type.
-    /// Satisfied (or refuted) once we know the closure's kind.
-    ClosureKind(I::DefId, I::GenericArgs, I::ClosureKind),
-
     /// `T1 <: T2`
     ///
     /// This obligation is created most often when we have two
@@ -173,7 +168,6 @@ where
     I::Term: Copy,
     I::CoercePredicate: Copy,
     I::SubtypePredicate: Copy,
-    I::ClosureKind: Copy,
     ClauseKind<I>: Copy,
 {
 }
@@ -183,9 +177,6 @@ impl<I: Interner> PartialEq for PredicateKind<I> {
         match (self, other) {
             (Self::Clause(l0), Self::Clause(r0)) => l0 == r0,
             (Self::ObjectSafe(l0), Self::ObjectSafe(r0)) => l0 == r0,
-            (Self::ClosureKind(l0, l1, l2), Self::ClosureKind(r0, r1, r2)) => {
-                l0 == r0 && l1 == r1 && l2 == r2
-            }
             (Self::Subtype(l0), Self::Subtype(r0)) => l0 == r0,
             (Self::Coerce(l0), Self::Coerce(r0)) => l0 == r0,
             (Self::ConstEquate(l0, l1), Self::ConstEquate(r0, r1)) => l0 == r0 && l1 == r1,
@@ -207,18 +198,12 @@ where
     I::Term: TypeFoldable<I>,
     I::CoercePredicate: TypeFoldable<I>,
     I::SubtypePredicate: TypeFoldable<I>,
-    I::ClosureKind: TypeFoldable<I>,
     ClauseKind<I>: TypeFoldable<I>,
 {
     fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
         Ok(match self {
             PredicateKind::Clause(c) => PredicateKind::Clause(c.try_fold_with(folder)?),
             PredicateKind::ObjectSafe(d) => PredicateKind::ObjectSafe(d.try_fold_with(folder)?),
-            PredicateKind::ClosureKind(d, g, k) => PredicateKind::ClosureKind(
-                d.try_fold_with(folder)?,
-                g.try_fold_with(folder)?,
-                k.try_fold_with(folder)?,
-            ),
             PredicateKind::Subtype(s) => PredicateKind::Subtype(s.try_fold_with(folder)?),
             PredicateKind::Coerce(s) => PredicateKind::Coerce(s.try_fold_with(folder)?),
             PredicateKind::ConstEquate(a, b) => {
@@ -242,18 +227,12 @@ where
     I::Term: TypeVisitable<I>,
     I::CoercePredicate: TypeVisitable<I>,
     I::SubtypePredicate: TypeVisitable<I>,
-    I::ClosureKind: TypeVisitable<I>,
     ClauseKind<I>: TypeVisitable<I>,
 {
     fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
         match self {
             PredicateKind::Clause(p) => p.visit_with(visitor),
             PredicateKind::ObjectSafe(d) => d.visit_with(visitor),
-            PredicateKind::ClosureKind(d, g, k) => {
-                d.visit_with(visitor)?;
-                g.visit_with(visitor)?;
-                k.visit_with(visitor)
-            }
             PredicateKind::Subtype(s) => s.visit_with(visitor),
             PredicateKind::Coerce(s) => s.visit_with(visitor),
             PredicateKind::ConstEquate(a, b) => {
@@ -313,9 +292,6 @@ impl<I: Interner> fmt::Debug for PredicateKind<I> {
             PredicateKind::ObjectSafe(trait_def_id) => {
                 write!(f, "ObjectSafe({trait_def_id:?})")
             }
-            PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
-                write!(f, "ClosureKind({closure_def_id:?}, {closure_args:?}, {kind:?})")
-            }
             PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
             PredicateKind::Ambiguous => write!(f, "Ambiguous"),
             PredicateKind::AliasRelate(t1, t2, dir) => {
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index f0b11dce9aa..ae48fff7899 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -766,7 +766,6 @@ pub struct GenericPredicates {
 pub enum PredicateKind {
     Clause(ClauseKind),
     ObjectSafe(TraitDef),
-    ClosureKind(ClosureDef, GenericArgs, ClosureKind),
     SubType(SubtypePredicate),
     Coerce(CoercePredicate),
     ConstEquate(Const, Const),
diff --git a/tests/ui/closure_context/issue-26046-fn-mut.stderr b/tests/ui/closure_context/issue-26046-fn-mut.stderr
index eeb40945242..5f0b6fd451c 100644
--- a/tests/ui/closure_context/issue-26046-fn-mut.stderr
+++ b/tests/ui/closure_context/issue-26046-fn-mut.stderr
@@ -1,16 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
-  --> $DIR/issue-26046-fn-mut.rs:4:19
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}`
+  --> $DIR/issue-26046-fn-mut.rs:8:5
    |
-LL |     let closure = || {
-   |                   ^^ this closure implements `FnMut`, not `Fn`
-LL |         num += 1;
-   |         --- closure is `FnMut` because it mutates the variable `num` here
-...
 LL |     Box::new(closure)
-   |     ----------------- the requirement to implement `Fn` derives from here
+   |     ^^^^^^^^^^^^^^^^^ expected an `Fn()` closure, found `{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}`
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}`
+   = note: wrap the `{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}` implements `FnMut`, but it must implement `Fn`, which is more general
    = note: required for the cast from `Box<{closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21}>` to `Box<(dyn Fn() + 'static)>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/closure_context/issue-26046-fn-once.stderr b/tests/ui/closure_context/issue-26046-fn-once.stderr
index 24773a1d7e3..da3dcf3e3af 100644
--- a/tests/ui/closure_context/issue-26046-fn-once.stderr
+++ b/tests/ui/closure_context/issue-26046-fn-once.stderr
@@ -1,16 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/issue-26046-fn-once.rs:4:19
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}`
+  --> $DIR/issue-26046-fn-once.rs:8:5
    |
-LL |     let closure = move || {
-   |                   ^^^^^^^ this closure implements `FnOnce`, not `Fn`
-LL |         vec
-   |         --- closure is `FnOnce` because it moves the variable `vec` out of its environment
-...
 LL |     Box::new(closure)
-   |     ----------------- the requirement to implement `Fn` derives from here
+   |     ^^^^^^^^^^^^^^^^^ expected an `Fn()` closure, found `{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}`
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}`
+   = note: wrap the `{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}` implements `FnOnce`, but it must implement `Fn`, which is more general
    = note: required for the cast from `Box<{closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26}>` to `Box<(dyn Fn() -> Vec<u8> + 'static)>`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
index 309c63e5293..189f08c12e9 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-array-diagnostics.stderr
@@ -1,16 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/closure-origin-array-diagnostics.rs:9:13
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/closure-origin-array-diagnostics.rs:9:13: 9:15}`
+  --> $DIR/closure-origin-array-diagnostics.rs:12:15
    |
-LL |     let c = || {
-   |             ^^ this closure implements `FnOnce`, not `Fn`
-LL |         let [_, _s] = s;
-   |                       - closure is `FnOnce` because it moves the variable `s` out of its environment
-LL |     };
 LL |     expect_fn(c);
-   |     --------- - the requirement to implement `Fn` derives from here
+   |     --------- ^ expected an `Fn()` closure, found `{closure@$DIR/closure-origin-array-diagnostics.rs:9:13: 9:15}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/closure-origin-array-diagnostics.rs:9:13: 9:15}`
+   = note: wrap the `{closure@$DIR/closure-origin-array-diagnostics.rs:9:13: 9:15}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/closure-origin-array-diagnostics.rs:9:13: 9:15}` implements `FnOnce`, but it must implement `Fn`, which is more general
 note: required by a bound in `expect_fn`
   --> $DIR/closure-origin-array-diagnostics.rs:5:17
    |
@@ -19,4 +17,4 @@ LL | fn expect_fn<F: Fn()>(_f: F) {}
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
index 3e77635f9e0..75c49d312a5 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics.stderr
@@ -1,16 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/closure-origin-tuple-diagnostics.rs:9:13
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/closure-origin-tuple-diagnostics.rs:9:13: 9:15}`
+  --> $DIR/closure-origin-tuple-diagnostics.rs:12:15
    |
-LL |     let c = || {
-   |             ^^ this closure implements `FnOnce`, not `Fn`
-LL |         let s = s.1;
-   |                 --- closure is `FnOnce` because it moves the variable `s.1` out of its environment
-LL |     };
 LL |     expect_fn(c);
-   |     --------- - the requirement to implement `Fn` derives from here
+   |     --------- ^ expected an `Fn()` closure, found `{closure@$DIR/closure-origin-tuple-diagnostics.rs:9:13: 9:15}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/closure-origin-tuple-diagnostics.rs:9:13: 9:15}`
+   = note: wrap the `{closure@$DIR/closure-origin-tuple-diagnostics.rs:9:13: 9:15}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/closure-origin-tuple-diagnostics.rs:9:13: 9:15}` implements `FnOnce`, but it must implement `Fn`, which is more general
 note: required by a bound in `expect_fn`
   --> $DIR/closure-origin-tuple-diagnostics.rs:5:17
    |
@@ -19,4 +17,4 @@ LL | fn expect_fn<F: Fn()>(_f: F) {}
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/closures/closure-wrong-kind.stderr b/tests/ui/closures/closure-wrong-kind.stderr
index 9ea55d764f3..c1c83014438 100644
--- a/tests/ui/closures/closure-wrong-kind.stderr
+++ b/tests/ui/closures/closure-wrong-kind.stderr
@@ -1,15 +1,13 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/closure-wrong-kind.rs:10:19
+error[E0277]: expected a `Fn(u32)` closure, found `{closure@$DIR/closure-wrong-kind.rs:10:19: 10:22}`
+  --> $DIR/closure-wrong-kind.rs:11:9
    |
-LL |     let closure = |_| foo(x);
-   |                   ^^^     - closure is `FnOnce` because it moves the variable `x` out of its environment
-   |                   |
-   |                   this closure implements `FnOnce`, not `Fn`
 LL |     bar(closure);
-   |     --- ------- the requirement to implement `Fn` derives from here
+   |     --- ^^^^^^^ expected an `Fn(u32)` closure, found `{closure@$DIR/closure-wrong-kind.rs:10:19: 10:22}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<(u32,)>` is not implemented for closure `{closure@$DIR/closure-wrong-kind.rs:10:19: 10:22}`
+   = note: `{closure@$DIR/closure-wrong-kind.rs:10:19: 10:22}` implements `FnOnce`, but it must implement `Fn`, which is more general
 note: required by a bound in `bar`
   --> $DIR/closure-wrong-kind.rs:6:11
    |
@@ -18,4 +16,4 @@ LL | fn bar<T: Fn(u32)>(_: T) {}
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-34349.stderr b/tests/ui/issues/issue-34349.stderr
index 8e9a16619f3..1235f44f4aa 100644
--- a/tests/ui/issues/issue-34349.stderr
+++ b/tests/ui/issues/issue-34349.stderr
@@ -1,16 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
-  --> $DIR/issue-34349.rs:16:17
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/issue-34349.rs:16:17: 16:19}`
+  --> $DIR/issue-34349.rs:21:11
    |
-LL |     let diary = || {
-   |                 ^^ this closure implements `FnMut`, not `Fn`
-LL |         farewell.push_str("!!!");
-   |         -------- closure is `FnMut` because it mutates the variable `farewell` here
-...
 LL |     apply(diary);
-   |     ----- ----- the requirement to implement `Fn` derives from here
+   |     ----- ^^^^^ expected an `Fn()` closure, found `{closure@$DIR/issue-34349.rs:16:17: 16:19}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/issue-34349.rs:16:17: 16:19}`
+   = note: wrap the `{closure@$DIR/issue-34349.rs:16:17: 16:19}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/issue-34349.rs:16:17: 16:19}` implements `FnMut`, but it must implement `Fn`, which is more general
 note: required by a bound in `apply`
   --> $DIR/issue-34349.rs:11:32
    |
@@ -19,4 +17,4 @@ LL |     fn apply<F>(f: F) where F: Fn() {
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
index eba65a61803..9a8c8123fba 100644
--- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
+++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr
@@ -1,57 +1,48 @@
-error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce`
-  --> $DIR/move-ref-patterns-closure-captures.rs:9:14
-   |
-LL |     let c1 = || {
-   |              ^^ this closure implements `FnOnce`, not `FnMut`
-...
-LL |         drop::<U>(_x1);
-   |                   --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
-...
+error[E0277]: expected a `FnMut()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
+  --> $DIR/move-ref-patterns-closure-captures.rs:17:19
+   |
 LL |     accept_fn_mut(&c1);
-   |     ------------- --- the requirement to implement `FnMut` derives from here
+   |     ------------- ^^^ expected an `FnMut()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `FnMut<()>` is not implemented for closure `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
+   = note: wrap the `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}` implements `FnOnce`, but it must implement `FnMut`, which is more general
 note: required by a bound in `accept_fn_mut`
   --> $DIR/move-ref-patterns-closure-captures.rs:4:31
    |
 LL |     fn accept_fn_mut(_: &impl FnMut()) {}
    |                               ^^^^^^^ required by this bound in `accept_fn_mut`
 
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/move-ref-patterns-closure-captures.rs:9:14
-   |
-LL |     let c1 = || {
-   |              ^^ this closure implements `FnOnce`, not `Fn`
-...
-LL |         drop::<U>(_x1);
-   |                   --- closure is `FnOnce` because it moves the variable `_x1` out of its environment
-...
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
+  --> $DIR/move-ref-patterns-closure-captures.rs:18:15
+   |
 LL |     accept_fn(&c1);
-   |     --------- --- the requirement to implement `Fn` derives from here
+   |     --------- ^^^ expected an `Fn()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}`
+   = note: wrap the `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/move-ref-patterns-closure-captures.rs:9:14: 9:16}` implements `FnOnce`, but it must implement `Fn`, which is more general
 note: required by a bound in `accept_fn`
   --> $DIR/move-ref-patterns-closure-captures.rs:5:27
    |
 LL |     fn accept_fn(_: &impl Fn()) {}
    |                           ^^^^ required by this bound in `accept_fn`
 
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
-  --> $DIR/move-ref-patterns-closure-captures.rs:20:14
-   |
-LL |     let c2 = || {
-   |              ^^ this closure implements `FnMut`, not `Fn`
-...
-LL |         drop::<&mut U>(_x2);
-   |                        --- closure is `FnMut` because it mutates the variable `_x2` here
-...
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:20:14: 20:16}`
+  --> $DIR/move-ref-patterns-closure-captures.rs:26:15
+   |
 LL |     accept_fn(&c2);
-   |     --------- --- the requirement to implement `Fn` derives from here
+   |     --------- ^^^ expected an `Fn()` closure, found `{closure@$DIR/move-ref-patterns-closure-captures.rs:20:14: 20:16}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/move-ref-patterns-closure-captures.rs:20:14: 20:16}`
+   = note: wrap the `{closure@$DIR/move-ref-patterns-closure-captures.rs:20:14: 20:16}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/move-ref-patterns-closure-captures.rs:20:14: 20:16}` implements `FnMut`, but it must implement `Fn`, which is more general
 note: required by a bound in `accept_fn`
   --> $DIR/move-ref-patterns-closure-captures.rs:5:27
    |
@@ -60,4 +51,4 @@ LL |     fn accept_fn(_: &impl Fn()) {}
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
index 846a44ce4d7..8a06d2f66bf 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr
@@ -1,15 +1,14 @@
-error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
-  --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13
+error[E0277]: expected a `Fn()` closure, found `{closure@$DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13: 14:15}`
+  --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:15:9
    |
-LL |     let c = || drop(y.0);
-   |             ^^      --- closure is `FnOnce` because it moves the variable `y` out of its environment
-   |             |
-   |             this closure implements `FnOnce`, not `Fn`
 LL |     foo(c);
-   |     --- - the requirement to implement `Fn` derives from here
+   |     --- ^ expected an `Fn()` closure, found `{closure@$DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13: 14:15}`
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `Fn<()>` is not implemented for closure `{closure@$DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13: 14:15}`
+   = note: wrap the `{closure@$DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13: 14:15}` in a closure with no arguments: `|| { /* code */ }`
+   = note: `{closure@$DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:14:13: 14:15}` implements `FnOnce`, but it must implement `Fn`, which is more general
 note: required by a bound in `foo`
   --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14
    |
@@ -20,4 +19,4 @@ LL |     where F: Fn()
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0525`.
+For more information about this error, try `rustc --explain E0277`.