swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.68k stars 10.39k forks source link

Compiler crash with generic result builders #72739

Closed carl314 closed 2 months ago

carl314 commented 8 months ago

Description

I'm hitting a compiler crash when adding a generic result builder annotation to a protocol function requirement.

Reproduction

Example 1, causes an assertion failure + crash backtrace:

protocol ResultProtocol {
    init()
}

protocol Producer {
    @Builder<R>
    func produceResult<R: ResultProtocol>(type: R.Type) -> R
}

@resultBuilder
struct Builder<T: ResultProtocol> {
    static func buildBlock(_ components: Int...) -> T {
        T.init()
    }
}

Example 2, results in a linker failure:

protocol Producer {
    @Builder<R>
    func produceResult<R>(type: R.Type) -> R
}

@resultBuilder
struct Builder<T> {
    static func buildBlock(_ components: Int...) -> T {
        // stub
        fatalError()
    }
}

Stack dump

Example 1:
error: compile command failed due to signal 6 (use -v to see invocation)
Assertion failed: (ctx.Diags.hadAnyError()), function evaluate, file TypeCheckType.cpp, line 5500.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.  Program arguments: /Users/me/Library/Developer/Toolchains/swift-5.10-RELEASE.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file GenericResultBuilderCrash.swift -target arm64-apple-macosx14.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -color-diagnostics -new-driver-path /Users/me/Library/Developer/Toolchains/swift-5.10-RELEASE.xctoolchain/usr/bin/swift-driver -empty-abi-descriptor -resource-dir /Users/me/Library/Developer/Toolchains/swift-5.10-RELEASE.xctoolchain/usr/lib/swift -module-name GenericResultBuilderCrash -plugin-path /Users/me/Library/Developer/Toolchains/swift-5.10-RELEASE.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Users/me/Library/Developer/Toolchains/swift-5.10-RELEASE.xctoolchain/usr/local/lib/swift/host/plugins -o /var/folders/wf/.../T/TemporaryDirectory.RdwrEo/GenericResultBuilderCrash-1.o
1.  Apple Swift version 5.10 (swift-5.10-RELEASE)
2.  Compiling with the current language version
3.  While evaluating request TypeCheckSourceFileRequest(source_file "GenericResultBuilderCrash.swift")
4.  While type-checking 'Producer' (at GenericResultBuilderCrash.swift:5:1)
5.  While type-checking 'produceResult(type:)' (at GenericResultBuilderCrash.swift:7:5)
6.  While evaluating request ResultBuilderTypeRequest(GenericResultBuilderCrash.(file).Producer.produceResult(type:)@GenericResultBuilderCrash.swift:7:10)
7.  While evaluating request CustomAttrTypeRequest(@Builder<R> , 0x13d960a70 ProtocolDecl name=Producer, non-generic)
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           0x0000000109bad558 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000109bac944 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000109badb94 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x0000000185deda24 _sigtramp + 56
4  libsystem_pthread.dylib  0x0000000185dbdcc0 pthread_kill + 288
5  libsystem_c.dylib        0x0000000185cc9a40 abort + 180
6  libsystem_c.dylib        0x0000000185cc8d30 err + 0
7  swift-frontend           0x0000000109fdddc8 swift::CustomAttrTypeRequest::evaluate(swift::Evaluator&, swift::CustomAttr*, swift::DeclContext*, swift::CustomAttrTypeKind) const (.cold.3) + 0
8  swift-frontend           0x0000000105f97870 swift::Type llvm::function_ref<swift::Type (swift::AbstractClosureExpr const*)>::callback_fn<adjustTypeAliasTypeInContext(swift::Type, swift::TypeAliasDecl*, swift::DeclContext*, swift::TypeResolutionOptions)::$_6>(long, swift::AbstractClosureExpr const*) + 0
9  swift-frontend           0x0000000105e49c64 llvm::Expected<swift::CustomAttrTypeRequest::OutputType> swift::Evaluator::getResultUncached<swift::CustomAttrTypeRequest>(swift::CustomAttrTypeRequest const&) + 268
10 swift-frontend           0x0000000105e49b0c llvm::Expected<swift::CustomAttrTypeRequest::OutputType> swift::Evaluator::getResultCached<swift::CustomAttrTypeRequest, (void*)0>(swift::CustomAttrTypeRequest const&) + 100
11 swift-frontend           0x0000000105e46e30 swift::CustomAttrTypeRequest::OutputType swift::evaluateOrDefault<swift::CustomAttrTypeRequest>(swift::Evaluator&, swift::CustomAttrTypeRequest, swift::CustomAttrTypeRequest::OutputType) + 44
12 swift-frontend           0x0000000105f69868 swift::ResultBuilderTypeRequest::evaluate(swift::Evaluator&, swift::ValueDecl*) const + 148
13 swift-frontend           0x000000010638e950 llvm::Expected<swift::ResultBuilderTypeRequest::OutputType> swift::Evaluator::getResultUncached<swift::ResultBuilderTypeRequest>(swift::ResultBuilderTypeRequest const&) + 272
14 swift-frontend           0x000000010638e738 llvm::Expected<swift::ResultBuilderTypeRequest::OutputType> swift::Evaluator::getResultCached<swift::ResultBuilderTypeRequest, (void*)0>(swift::ResultBuilderTypeRequest const&) + 384
15 swift-frontend           0x00000001062f1a30 swift::ResultBuilderTypeRequest::OutputType swift::evaluateOrDefault<swift::ResultBuilderTypeRequest>(swift::Evaluator&, swift::ResultBuilderTypeRequest, swift::ResultBuilderTypeRequest::OutputType) + 52
16 swift-frontend           0x0000000105e2030c swift::checkAccessControl(swift::Decl*) + 8560
17 swift-frontend           0x0000000105ed9e24 (anonymous namespace)::DeclChecker::visitFuncDecl(swift::FuncDecl*) + 120
18 swift-frontend           0x0000000105ed04b0 (anonymous namespace)::DeclChecker::visit(swift::Decl*) + 404
19 swift-frontend           0x0000000105ed9738 (anonymous namespace)::DeclChecker::visitProtocolDecl(swift::ProtocolDecl*) + 156
20 swift-frontend           0x0000000105ed0810 (anonymous namespace)::DeclChecker::visit(swift::Decl*) + 1268
21 swift-frontend           0x0000000105ed0304 swift::TypeChecker::typeCheckDecl(swift::Decl*, bool) + 148
22 swift-frontend           0x0000000105fa7ae0 swift::TypeCheckSourceFileRequest::evaluate(swift::Evaluator&, swift::SourceFile*) const + 168
23 swift-frontend           0x0000000105fa9c28 llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultUncached<swift::TypeCheckSourceFileRequest>(swift::TypeCheckSourceFileRequest const&) + 280
24 swift-frontend           0x0000000105fa9aac llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultCached<swift::TypeCheckSourceFileRequest, (void*)0>(swift::TypeCheckSourceFileRequest const&) + 64
25 swift-frontend           0x0000000105fa795c swift::TypeCheckSourceFileRequest::OutputType swift::evaluateOrDefault<swift::TypeCheckSourceFileRequest>(swift::Evaluator&, swift::TypeCheckSourceFileRequest, swift::TypeCheckSourceFileRequest::OutputType) + 44
26 swift-frontend           0x0000000104f7feec bool llvm::function_ref<bool (swift::SourceFile&)>::callback_fn<swift::CompilerInstance::performSema()::$_7>(long, swift::SourceFile&) + 16
27 swift-frontend           0x0000000104f79c14 swift::CompilerInstance::forEachFileToTypeCheck(llvm::function_ref<bool (swift::SourceFile&)>) + 76
28 swift-frontend           0x0000000104f79ba8 swift::CompilerInstance::performSema() + 92
29 swift-frontend           0x0000000104d8f064 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 60
30 swift-frontend           0x0000000104d813cc performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 748
31 swift-frontend           0x0000000104d8043c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2096
32 swift-frontend           0x0000000104c48858 swift::mainEntry(int, char const**) + 2160
33 dyld                     0x0000000185a3d0e0 start + 2360
error: fatalError

---------------------
Example 2:
error: link command failed with exit code 1 (use -v to see invocation)
ld: library 'System' not found
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
error: fatalError

Expected behavior

The code examples should compile.

Environment

Compiler crash, 5.10, 5.9.2, ..., 5.7.3, 5.4 -- every swift.org open source release Xcode toolchain:

Apple Swift version 5.10 (swift-5.10-RELEASE) Target: arm64-apple-macosx14.0

Also occurs with nightly development snapshots (March 31, 2024):

Apple Swift version 6.0-dev (LLVM a8cd54c4da01fef, Swift 365da5f0ff87343) Target: arm64-apple-macosx14.0

BUT: Compiles with the 5.10 toolchain shipping with Xcode 15.3 (15E204a) and in the swift:latest (05a85cf71d57) docker container:

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

Swift version 5.10 (swift-5.10-RELEASE) Target: aarch64-unknown-linux-gnu

Additional information

may be related to #61250 ...

FB13823026

xedin commented 3 months ago

@AnthonyLatsis This seems to be related to type resolution changes you have been working on.

xedin commented 3 months ago

It might be because dc provided by CustomAttrTypeRequest is a protocol nominal instead of the method it's actually attached to.

AnthonyLatsis commented 2 months ago

It might be because dc provided by CustomAttrTypeRequest is a protocol nominal instead of the method it's actually attached to.

Yeah. But the reason this crashes instead of erroring out is that name lookup still finds the method’s generic parameter when given the wrong, nominal declaration context. I wonder if there is anything relying on this name lookup behavior.