nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.9k stars 639 forks source link

"error: Expected { on line" with a guard and a double subscript #1095

Closed juri closed 2 years ago

juri commented 2 years ago

This is a valid Swift file:

#!/usr/bin/swift

let array: [[String: Any]] = [
    ["foo": "bar"],
]

guard let value = array[0]["foo"] as? String else {
    fatalError("oops")
}

print("found value:", value)

Running SwiftFormat 0.49.1 on it with no configuration reports the following:

swiftformat --lint Guard.swift
Running SwiftFormat...
(lint mode - no files will be changed.)
warning: No Swift version was specified, so some formatting features were disabled. Specify the version of Swift you are using with the --swiftversion option, or by adding a .swift-version file to your project.
error: Expected { on line 7 in /path/to/Guard.swift.

It looks like it requires that double subscript to trigger it, it didn't happen with a simple dict.

This worked with SwiftFormat 0.48.x, but seems to have broken with 0.49.

zacwest commented 2 years ago

This also occurs for a function returning a dictionary, e.g.:

if let test = value()["hi"] {
    print("hi")
}

produces "error: Expected { on line 1"

nicklockwood commented 2 years ago

@juri @zacwest fixed in 0.49.2

shkhaliq commented 2 years ago

Still running into this on 0.49.2:

guard let row: Row = promotionSections[indexPath.section][indexPath.row] else { return UITableViewCell() }

produces

error: Expected { on line 
nicklockwood commented 2 years ago

@shkhaliq I'm not able to reproduce the error on 0.49.2 with a file containing just that line. Can you provide a standalone example that demonstrates the problem? Or perhaps something in your .swiftformat config is needed to reproduce it?

shkhaliq commented 2 years ago

Okay how about you try this in an empty file. I can reproduce it then

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let row: Row = promotionSections[indexPath.section][indexPath.row] else { return UITableViewCell() }
        let cell = tableView.dequeueReusable(RowTableViewCell.self, forIndexPath: indexPath)
        cell.update(row: row)
        return cell
    }
nicklockwood commented 2 years ago

@shkhaliq OK, I can reproduce with this example, thanks 👍

nicklockwood commented 2 years ago

@shkhaliq this appears to be fixed in 0.49.3

shkhaliq commented 2 years ago

@nicklockwood Yes thank you for the fix!