diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 21c158fd0fddd..ee41d840bae92 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -601,10 +601,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!(?obligation, "confirm_fn_pointer_candidate");
 
         let tcx = self.tcx();
-        let self_ty = self
+
+        let Some(self_ty) = self
             .infcx
-            .shallow_resolve(obligation.self_ty().no_bound_vars())
-            .expect("fn pointer should not capture bound vars from predicate");
+            .shallow_resolve(obligation.self_ty().no_bound_vars()) else
+        {
+            // FIXME: Ideally we'd support `for<'a> fn(&'a ()): Fn(&'a ())`,
+            // but we do not currently. Luckily, such a bound is not
+            // particularly useful, so we don't expect users to write
+            // them often.
+            return Err(SelectionError::Unimplemented);
+        };
+
         let sig = self_ty.fn_sig(tcx);
         let trait_ref = closure_trait_ref_and_return_type(
             tcx,
diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr b/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr
new file mode 100644
index 0000000000000..9af6bc45c7a06
--- /dev/null
+++ b/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr
@@ -0,0 +1,19 @@
+error[E0277]: expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())`
+  --> $DIR/fn-ptr.rs:12:5
+   |
+LL |     ice();
+   |     ^^^ expected an `Fn<(&'w (),)>` closure, found `fn(&'w ())`
+   |
+   = help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())`
+note: required by a bound in `ice`
+  --> $DIR/fn-ptr.rs:7:25
+   |
+LL | fn ice()
+   |    --- required by a bound in this function
+LL | where
+LL |     for<'w> fn(&'w ()): Fn(&'w ()),
+   |                         ^^^^^^^^^^ required by this bound in `ice`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.rs b/tests/ui/higher-rank-trait-bounds/fn-ptr.rs
new file mode 100644
index 0000000000000..853160f961245
--- /dev/null
+++ b/tests/ui/higher-rank-trait-bounds/fn-ptr.rs
@@ -0,0 +1,14 @@
+// revisions: classic next
+//[next] compile-flags: -Ztrait-solver=next
+//[next] check-pass
+
+fn ice()
+where
+    for<'w> fn(&'w ()): Fn(&'w ()),
+{
+}
+
+fn main() {
+    ice();
+    //[classic]~^ ERROR expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())`
+}