Description
Description
I made a typo in my Vapor project model definition by mistyping Model
and this caused a crash. I later managed to distil this crash and recreate it in a standalone repository. Here is the link: https://github.com/RussBaz/SwiftCompilerBug1. Just clone it and run a build command. The compiler will crash.
Please have a look at Sources/App/Models/Todo.swift
file. Type checking of the QueryBuilder
extension method (constrained to Todo
model) in that file crashes the compiler when the Todo
model is conforming to a non-existent protocol.
Reproduction
import Fluent
import Foundation
final class Todo: MyModel, @unchecked Sendable {
static let schema = "todos"
@ID(key: .id)
var id: UUID?
@OptionalField(key: "title")
var title: String?
@OptionalField(key: "done_at")
var doneAt: Date?
@Parent(key: "user_id")
var user: User
@Children(for: \.$todo)
var items: [TodoItem]
init() {}
init(id: UUID? = nil, title: String) {
self.id = id
self.title = title
}
}
extension QueryBuilder where Model == Todo {
func filterToDos() -> Self {
join(User.self, on: \User.$id == \Todo.$user.$id)
.group(.or) { outer in
outer.filter(Todo.self, \.$title == .null)
.filter(Todo.self, \.$doneAt == nil)
}
.join(TodoItem.self, on: \TodoItem.$todo.$id == \Todo.$id)
.filter(Todo.self, \.$title ~~ "another")
}
}
Stack dump
1. Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
2. Compiling with the current language version
3. While evaluating request TypeCheckSourceFileRequest(source_file "/Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift")
4. While evaluating request TypeCheckFunctionBodyRequest(App.(file).QueryBuilder extension.filterToDos()@/Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift:41:10)
5. While type-checking statement at [/Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift:41:32 - line:49:5] RangeText="{
join(User.self, on: \User.$id == \Todo.$user.$id)
.group(.or) { outer in
outer.filter(Todo.self, \.$title == .null)
.filter(Todo.self, \.$doneAt == nil)
}
.join(TodoItem.self, on: \TodoItem.$todo.$id == \Todo.$id)
.filter(Todo.self, \.$title ~~ "another")
"
6. While type-checking statement at [/Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift:42:9 - line:48:53] RangeText="join(User.self, on: \User.$id == \Todo.$user.$id)
.group(.or) { outer in
outer.filter(Todo.self, \.$title == .null)
.filter(Todo.self, \.$doneAt == nil)
}
.join(TodoItem.self, on: \TodoItem.$todo.$id == \Todo.$id)
.filter(Todo.self, \.$title ~~ "another""
7. While type-checking expression at [/Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift:42:9 - line:48:53] RangeText="join(User.self, on: \User.$id == \Todo.$user.$id)
.group(.or) { outer in
outer.filter(Todo.self, \.$title == .null)
.filter(Todo.self, \.$doneAt == nil)
}
.join(TodoItem.self, on: \TodoItem.$todo.$id == \Todo.$id)
.filter(Todo.self, \.$title ~~ "another""
8. While type-checking-target starting at /Users/user/Projects/GitHub/SwiftCompilerBug1/Sources/App/Models/Todo.swift:48:14
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 swift-frontend 0x0000000107bd3f3c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1 swift-frontend 0x0000000107bd30f8 llvm::sys::RunSignalHandlers() + 112
2 swift-frontend 0x0000000107bd4544 SignalHandler(int) + 360
3 libsystem_platform.dylib 0x000000018c4c7584 _sigtramp + 56
4 swift-frontend 0x000000010361de88 swift::constraints::DisjunctionStep::~DisjunctionStep() + 44
5 swift-frontend 0x000000010361ca8c swift::constraints::DisjunctionStep::~DisjunctionStep() + 12
6 swift-frontend 0x0000000103605790 swift::constraints::ConstraintSystem::solveImpl(llvm::SmallVectorImpl<swift::constraints::Solution>&) + 1132
7 swift-frontend 0x00000001036c1d0c swift::constraints::ConstraintSystem::salvage() + 212
8 swift-frontend 0x0000000103607a88 swift::constraints::ConstraintSystem::solve(swift::constraints::SyntacticElementTarget&, swift::FreeTypeVariableBinding) + 1756
9 swift-frontend 0x00000001037f3b48 swift::TypeChecker::typeCheckTarget(swift::constraints::SyntacticElementTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 584
10 swift-frontend 0x00000001037f37dc swift::TypeChecker::typeCheckExpression(swift::constraints::SyntacticElementTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 436
11 swift-frontend 0x00000001037f35d4 swift::TypeChecker::typeCheckExpression(swift::Expr*&, swift::DeclContext*, swift::constraints::ContextualTypeInfo, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 92
12 swift-frontend 0x0000000103907cdc swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 7136
13 swift-frontend 0x0000000103905fc4 bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::Stmt>(swift::Stmt*&) + 316
14 swift-frontend 0x0000000103901008 (anonymous namespace)::StmtChecker::typeCheckASTNode(swift::ASTNode&) + 104
15 swift-frontend 0x0000000103906224 swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 296
16 swift-frontend 0x0000000103903a6c bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::BraceStmt>(swift::BraceStmt*&) + 316
17 swift-frontend 0x00000001039027dc swift::TypeCheckFunctionBodyRequest::evaluate(swift::Evaluator&, swift::AbstractFunctionDecl*) const + 732
18 swift-frontend 0x0000000103ce3f68 swift::TypeCheckFunctionBodyRequest::OutputType swift::evaluateOrDefault<swift::TypeCheckFunctionBodyRequest>(swift::Evaluator&, swift::TypeCheckFunctionBodyRequest, swift::TypeCheckFunctionBodyRequest::OutputType) + 884
19 swift-frontend 0x0000000103950520 swift::TypeCheckSourceFileRequest::evaluate(swift::Evaluator&, swift::SourceFile*) const + 608
20 swift-frontend 0x0000000103956988 llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultUncached<swift::TypeCheckSourceFileRequest>(swift::TypeCheckSourceFileRequest const&) + 664
21 swift-frontend 0x0000000103950240 swift::TypeCheckSourceFileRequest::OutputType swift::evaluateOrDefault<swift::TypeCheckSourceFileRequest>(swift::Evaluator&, swift::TypeCheckSourceFileRequest, swift::TypeCheckSourceFileRequest::OutputType) + 228
22 swift-frontend 0x00000001026e0854 swift::CompilerInstance::performSema() + 196
23 swift-frontend 0x00000001024d5634 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1352
24 swift-frontend 0x00000001024d36d0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4968
25 swift-frontend 0x0000000102462e8c swift::mainEntry(int, char const**) + 2612
26 dyld 0x000000018c10e0e0 start + 2360
Expected behavior
Only an error should be raised. The compiler should not crash.
Environment
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
macOS: 14.4.1 (23E224)
Additional information
It also happens on the Intel mac.