Skip to content

Commit

Permalink
Rollup merge of #108834 - compiler-errors:fn-ptr-fn-obl, r=spastorino
Browse files Browse the repository at this point in the history
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 :^)
  • Loading branch information
matthiaskrgr committed Mar 10, 2023
2 parents 233ed35 + 4fe232b commit bee8473
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
14 changes: 11 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr
Original file line number Diff line number Diff line change
@@ -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`.
14 changes: 14 additions & 0 deletions tests/ui/higher-rank-trait-bounds/fn-ptr.rs
Original file line number Diff line number Diff line change
@@ -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 ())`
}

0 comments on commit bee8473

Please sign in to comment.