Rollup merge of #108834 - compiler-errors:fn-ptr-fn-obl, r=spastorino

Do not ICE when we have fn pointer `Fn` obligations with bound vars in the self type

We never supported solving `for<'a> fn(&'a ()): Fn(&'a ())` -- I tried to add that support in #104929, but iirc `@lcnr` wanted to support this more generally by eagerly instantiating trait predicate binders with placeholders. That never happened due to blockers in the old solver, but we probably shouldn't ICE in any case.

On the bright side, this passes on the new solver :^)
This commit is contained in:
Matthias Krüger 2023-03-10 19:59:18 +01:00 committed by GitHub
commit bee84733ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 3 deletions

View File

@ -601,10 +601,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?obligation, "confirm_fn_pointer_candidate"); debug!(?obligation, "confirm_fn_pointer_candidate");
let tcx = self.tcx(); let tcx = self.tcx();
let self_ty = self
let Some(self_ty) = self
.infcx .infcx
.shallow_resolve(obligation.self_ty().no_bound_vars()) .shallow_resolve(obligation.self_ty().no_bound_vars()) else
.expect("fn pointer should not capture bound vars from predicate"); {
// 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 sig = self_ty.fn_sig(tcx);
let trait_ref = closure_trait_ref_and_return_type( let trait_ref = closure_trait_ref_and_return_type(
tcx, tcx,

View File

@ -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`.

View File

@ -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 ())`
}