Vapor 3: Swift 5.2 Regression

Swift 5.2 (released in Xcode 11.4) has a regression causing valid Vapor 3 Fluent code to no longer compile.

You can read more about this regression in SR-12354. This forum post will show you a couple ways to work around for the (hopefully short) time being.

The regression affects Vapor 3 projects using Fluent and migrations. The bug affects code using leading-dot syntax to reference a database identifier when configuring migrations.

migrations.add(model: Todo.self, database: .sqlite)

The above code, which compiles fine in Swift 5.1, will now result in the following error:

Reference to member 'sqlite' cannot be resolved without a contextual type

This can be fixed by using an explicit type instead of leading-dot syntax:

migrations.add(model: Todo.self, database: DatabaseIdentifier<SQLiteDatabase>.sqlite)

It can also be fixed by specifying the Database typealias on the model.

final class Todo: SQLiteModel {
    // Swift 5.2 requires this even though SQLiteModel constrains Database
    // to this exact type. 
    typealias Database = SQLiteDatabase
    ...
}
9 Likes

This looks kinda similar to a bug I have with Vapor 4:

class UserSessionAuthenticator: SessionAuthenticator {
    func resolve(sessionID: MyType.SessionID, for request: Request) -> EventLoopFuture<MyType?> {
        return MyType.query(on: request.db).filter(\.$id == sessionID).first()
    }
    
    typealias User = MyType
}

This does not compile anymore if you don't add the explicit typealias User = MyType which looks like a compiler bug maybe?

CC @Douglas_Gregor . Doug and @tanner0101 do we understand how this is not caught by the source compatibility suite?

This issue only shows up in projects. Both the vapor and fluent packages continue to compile fine. Seems like we need to add some example vapor projects to the compat suite.

1 Like

Ah, so Vapor's test suite doesn't happen to exercise this? Or does the source compat suite not run the tests?

Looks like the compat suite only has the Fluent module which continues to pass tests. If it would have been testing the drivers as well (FluentSQLite, FluentMySQL, and FluentPostgres) it would have seen the issue. The drivers build fine, but their test suites don't.

It also doesn't affect every invocation of it. I have a project with around 40 models and migrations in, only 7 needed changing to make the type checker happy

Oh, and as for Vapor example projects, the Vapor TIL project and SteamPressExample should be added, both are fairly large and complex Vapor projects

2 Likes

Simple way:
extension Todo: PostgreSQLMigration { }