2

Non-diverging functions work fine

fn test(f: &Fn() -> u8) {}

But I can't accept a diverging function like this

fn test_diverging(f: &Fn() -> !) {}

I get the following error

error[E0658]: The `!` type is experimental (see issue #35121)
  --> examples/two_tasks.rs:44:31
   |
44 | fn test_diverging(f: &Fn() -> !) {}
   |                               ^

Looking at issue #35121 I could see how that might fix it but in the mean time is there a work around?

hellow
  • 12,430
  • 7
  • 56
  • 79
joegtp
  • 712
  • 6
  • 17

4 Answers4

9

! in some contexts is still experimental, which means it's not available on the stable compiler (1.33 as of today). You can use it on the nightly compiler, but you have to opt-in explicitly to feature(never_type):

#![feature(never_type)]
fn test_diverging(f: &Fn() -> !) {}

(playground)

Be aware this means the feature may yet change before stabilization, so you're accepting the risk that a future compiler version will break your code.

See also

trent
  • 25,033
  • 7
  • 51
  • 90
6

Using the never type in functions and function pointer types is already stable. So if you don't need to use the Fn trait, you can just use this:

fn test_diverging(f: fn() -> !) {}
//                   ^ note the lowercase f

test_diverging(|| panic!("ouch"));

That way you can't pass closures that reference their environment, but non-capturing closures and standard functions work fine.

Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
2

If you want to stay on stable, you can use Void (basically an enum with no variants, which can't be constructed without unsafe) as a workaround.

Playground link

1

To use unstable feature you need to use nightly toolchain and active the desired unstable feature.

#![feature(never_type)]

fn test_diverging(f: &Fn() -> !) {}

See also:

Stargateur
  • 24,473
  • 8
  • 65
  • 91