Skip to content

A typo in a protocol name can crash the compiler under certain conditions #73668

Open
@RussBaz

Description

@RussBaz

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrontendArea → compiler: FrontendbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwaretype checkerArea → compiler: Semantic analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions