Search code examples
swiftswift3

swift 3.0.2 gives ambitious error ''Type 'bool' is broken"


i am using this struct and using this

struct Ride {
  var isRideForNow: Bool!    
}
 var sheduleRide: Ride?
 sheduleRide = Ride()
 sheduleRide?.isRideForNow = false

When i am using like this it works fine

 if (sheduleRide?.isRideForNow)! {
   //some code
 }

But i don't know why below code give the error "Type 'bool' is broken" even there is no optional chaining inside this

 if (sheduleRide!.isRideForNow) {
   //some code
 }

Solution

  • It's a useless error message – which appears only to be present in Swift versions 3.0 to 3.0.2. The problem is that Swift is not implicitly unwrapping the optional, as it thinks you're trying to do an optional check.

    The solution therefore, as @vacawama says, is to simply explicitly unwrap the optional:

    if sheduleRide!.isRideForNow! {
        // some code
    }
    

    (which of course will crash if either sheduleRide or isRideForNow is nil)

    However, the fact that Swift isn't implicitly unwrapping the IUO here, in my view, is not in line with the IUO behaviour detailed in SE-0054 – in that IUOs should be treated as strong optionals where they can be type-checked as them, but otherwise should be implicitly unwrapped.

    In a boolean condition, the compiler cannot type-check the expression as a strong optional, therefore really it should be implicitly unwrapped. This behaviour was filed as a bug and fixed in this pull request, so the statement:

    if sheduleRide!.isRideForNow {
        // some code
    }
    

    now compiles fine in Swift 3.1.

    But really, as @vadian says, you should be thinking about whether isRideForNow should be an IUO. You should only make it one if it needs to have delayed initialisation (and can't otherwise
    be lazy).

    If you're giving it a value upon initialisation, then it can be non-optional:

    struct Ride {
        var isRideForNow: Bool
    }
    
    var sheduleRide = Ride(isRideForNow: false)