         var parser = parser
         var value = 0
 
-        while true {
+        // This would be more natural as `while true { ... }` with a meaningful .Done case,
+        // but that causes compile time explosion in Swift 2.2. :-|
+        while parser.state != .Done {
             switch parser.state {
             case .LeadingMinus:
                 sign = .Negative

        var exponent = Double(0)
        var position = 0.1

        while true {
            switch parser.state {
            case .LeadingMinus, .LeadingZero, .PreDecimalDigits:
                assertionFailure("Invalid internal state while parsing number")

                assertionFailure("Invalid internal state while parsing number")

            case .Done:
                fatalError("impossible condition")
            }
        }

        guard case let (signedValue, false) = Int.multiplyWithOverflow(sign.rawValue, value) else {
            throw InternalError.NumberOverflow(offset: parser.start)
        }

        loc = parser.loc
        return .Int(signedValue)
    }

    private mutating func decodeFloatingPointValue(parser: NumberParser, sign: Sign, value: Double) throws -> JSON {
