theos/orion

Cannot use implicitly unwrapped optional types in hooked function signatures

EamonTracey opened this issue · 2 comments

class MyHook: ClassHook<SomeClass> {

    func function(arg: Any) {}

}

and

class MyHook: ClassHook<SomeClass> {

    func function(arg: Any?) {}

}

both compile as expected.
However, if I do

class MyHook: ClassHook<SomeClass> {

    func function(arg: Any!) {}

}

I receive the following errors:

error: using '!' is not allowed here; perhaps '?' was intended?
    private static let orion_sel1 = #selector(function(arg:) as (Self) -> (Any!) -> Void)
error: using '!' is not allowed here; perhaps '?' was intended?
    private static var orion_orig1: @convention(c) (Target, Selector, Any!) -> Void = { target, _cmd, arg1 in
error: using '!' is not allowed here; perhaps '?' was intended?
            callSuper((@convention(c) (UnsafeRawPointer, Selector, Any!) -> Void).self) { $0($1, Self.orion_sel1, arg1) }

I do not believe this behavior is intended.

Implicitly unwrapped optionals are not types, they are sugar around optionals. You can’t really use them in very many places anymore.

^ what @saagarjha said. This is an (intentional) limitation in Swift more than it is in Orion: see SE-0054. If the method you're hooking appears to use an IUO in its signature, you can use a regular optional instead to achieve the same thing. The only difference is you'll need to manually unwrap arguments, but that's arguably better than the alternative since it makes you think about what could happen if the value is nil.