swiftlang / swift

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

[SR-9712] Swift 5 fails to recognise `thin` closure (assertion failure) #52150

Open dmcyk opened 5 years ago

dmcyk commented 5 years ago
Previous ID SR-9712
Radar rdar://problem/47446870
Original Reporter @dmcyk
Type Bug
Environment Swift 5 - swift-5.0-DEVELOPMENT-SNAPSHOT-2019-01-18 Swift 4.2.1 - Xcode 10.1
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, CompilerCrash | |Assignee | None | |Priority | Medium | md5: 5fd2a93f448c3abced4efaa73416b634

cloned from:

Issue Description:

Problem

There seems to be regression in Swift 5, where the compiler fails to recognise `thin` closure and crashes with failed assertion.
Whereas same code in Swift 4.2.1 compiles.

Code

Given module foo:

// foo.swift
import Foundation

public enum Foo<Success, Failure: Error> {

  case success(Success)

  case failure(Failure)

  @inline(__always)
  public func mapContext<T, NewSuccess>(
    _ context: inout T,
    _ transform: @convention(thin) (Success, inout T) -> NewSuccess
  ) -> Foo<NewSuccess, Failure> {
    switch self {
    case let .success(success):
      return .success(transform(success, &context))
    case let .failure(failure):
      return .failure(failure)
    }
  }
}

#if swift(>=5.0)
#else
extension Never: Error {}
#endif

and our client module:

// main.swift
import Foundation
import foo

#if swift(>=5.0)
dump("swift-5.0")
#else
dump("swift-4.2")
#endif

let val = Foo<Int, Never>.success(10)
var i = 0
val.mapContext(&i) {
  return $1
}

Compilation

$ swiftc -force-single-frontend-invocation -whole-module-optimization -emit-module-path foo.swiftmodule -O -emit-library -module-name foo foo.swift
$ swiftc -force-single-frontend-invocation -whole-module-optimization -emit-executable -I . -L . -O -lfoo -module-name repro main.swift

Client module compilation output

Swift 4.2

main.swift:13:5: warning: result of call to 'mapContext' is unused
val.mapContext(&i) {
    ^         ~~~~~~

Swift 5

main.swift:13:5: warning: result of call to 'mapContext' is unused
val.mapContext(&i) {
    ^         ~~~~~~
Assertion failed: (expectedFnType->getExtInfo().hasContext() && "conversion thunk will not be thin!"), function transformFunction, file /Users/buildnode/jenkins/workspace/oss-swift-5.0-package-osx/swift/lib/SILGen/SILGenPoly.cpp, line 3367.
Stack dump:
0.  Program arguments: /Library/Developer/Toolchains/swift-5.0-DEVELOPMENT-SNAPSHOT-2019-01-18-a.xctoolchain/usr/bin/swift -frontend -c main.swift -target x86_64-apple-darwin18.2.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -I . -O -color-diagnostics -module-name repro -o /var/folders/mc/pqh3yf651nx_p_m9jdhlt1f80000gn/T/repro-6eb494.o
0  swift                    0x00000001126a4808 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swift                    0x00000001126a3a85 llvm::sys::RunSignalHandlers() + 85
2  swift                    0x00000001126a4e12 SignalHandler(int) + 258
3  libsystem_platform.dylib 0x00007fff5fc47b3d _sigtramp + 29
4  swift                    0x00000001139bbae5 cmark_strbuf__initbuf + 131208
5  libsystem_c.dylib        0x00007fff5fb051c9 abort + 127
6  libsystem_c.dylib        0x00007fff5facd868 basename_r + 0
7  swift                    0x000000010f3fcfee (anonymous namespace)::Transform::transform(swift::Lowering::ManagedValue, swift::Lowering::AbstractionPattern, swift::CanType, swift::Lowering::AbstractionPattern, swift::CanType, swift::Lowering::SGFContext) + 10734
8  swift                    0x000000010f3f9fab swift::Lowering::SILGenFunction::emitSubstToOrigValue(swift::SILLocation, swift::Lowering::ManagedValue, swift::Lowering::AbstractionPattern, swift::CanType, swift::Lowering::SGFContext) + 171
9  swift                    0x000000010f3896ed swift::Lowering::Conversion::emit(swift::Lowering::SILGenFunction&, swift::SILLocation, swift::Lowering::ManagedValue, swift::Lowering::SGFContext) const + 749
10 swift                    0x000000010f3892fe swift::Lowering::ConvertingInitialization::finishEmission(swift::Lowering::SILGenFunction&, swift::SILLocation, swift::Lowering::ManagedValue) + 94
11 swift                    0x000000010f3890e0 swift::Lowering::SILGenFunction::emitConvertedRValue(swift::SILLocation, swift::Lowering::Conversion const&, swift::Lowering::SGFContext, llvm::function_ref<swift::Lowering::ManagedValue (swift::Lowering::SILGenFunction&, swift::SILLocation, swift::Lowering::SGFContext)>) + 384
12 swift                    0x000000010f31bc42 swift::Lowering::ArgumentSource::getConverted(swift::Lowering::SILGenFunction&, swift::Lowering::Conversion const&, swift::Lowering::SGFContext) && + 114
13 swift                    0x000000010f354657 (anonymous namespace)::ArgEmitter::emit(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 4055
14 swift                    0x000000010f354f4d (anonymous namespace)::ArgEmitter::emitExpanded(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 685
15 swift                    0x000000010f3536f6 (anonymous namespace)::ArgEmitter::emit(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 118
16 swift                    0x000000010f34cc50 (anonymous namespace)::ArgEmitter::emitTopLevel(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 2784
17 swift                    0x000000010f360077 (anonymous namespace)::CallSite::emit(swift::Lowering::SILGenFunction&, swift::Lowering::AbstractionPattern, swift::CanTypeWrapper<swift::SILFunctionType>, (anonymous namespace)::ParamLowering&, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, llvm::SmallVectorImpl<(anonymous namespace)::DelayedArgument>&, llvm::Optional<swift::ForeignErrorConvention> const&, swift::ImportAsMemberStatus) && + 1047
18 swift                    0x000000010f35f77c (anonymous namespace)::CallEmission::emitArgumentsForNormalApply(swift::CanTypeWrapper<swift::FunctionType>&, swift::Lowering::AbstractionPattern&, swift::CanTypeWrapper<swift::SILFunctionType>, llvm::Optional<swift::ForeignErrorConvention> const&, swift::ImportAsMemberStatus, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, llvm::Optional<swift::SILLocation>&, swift::CanTypeWrapper<swift::FunctionType>&) + 1772
19 swift                    0x000000010f344496 (anonymous namespace)::CallEmission::apply(swift::Lowering::SGFContext) + 3094
20 swift                    0x000000010f343780 swift::Lowering::SILGenFunction::emitApplyExpr(swift::Expr*, swift::Lowering::SGFContext) + 2016
21 swift                    0x000000010f3ad7c0 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 80
22 swift                    0x000000010f3a294e swift::Lowering::SILGenFunction::emitIgnoredExpr(swift::Expr*) + 1198
23 swift                    0x000000010f338084 swift::Lowering::SILGenModule::visitTopLevelCodeDecl(swift::TopLevelCodeDecl*) + 564
24 swift                    0x000000010f338896 swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*) + 822
25 swift                    0x000000010f3397f3 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*) + 371
26 swift                    0x000000010f339d00 swift::performSILGeneration(swift::ModuleDecl*, swift::SILOptions&) + 16
27 swift                    0x000000010eabea84 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 9332
28 swift                    0x000000010eabb57d swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3021
29 swift                    0x000000010ea6d49e main + 686
30 libdyld.dylib            0x00007fff5fa5ced9 start + 1
<unknown>:0: error: unable to execute command: Abort trap: 6
<unknown>:0: error: compile command failed due to signal 6 (use -v to see invocation)
dmcyk commented 5 years ago

cc aschwaighofer@apple.com (JIRA User) could this be maybe related to https://github.com/apple/swift/pull/21933 ?

dmcyk commented 5 years ago

guess that PR isn't direct cause of it. I tried also snapshot from 01-05 and got same assertion crash

belkadan commented 5 years ago

We probably should have underscored thin a long time ago, but it's a little late now. @slavapestov, @jckarter, this look familiar?

jckarter commented 5 years ago

We should still underscore it because it hasn't worked and doesn't work. You can't use @convention(thin) unless you're a compiler engineer. Chances are good that you'd hit this exact same assertion, or a different assertion, in an asserts build of Swift 4.2, but because Xcode doesn't ship Swift with assertions enabled, it's instead quietly miscompiling.

dmcyk commented 5 years ago

I see. if that's known, expected then its fine for me if you want to close this ticket. I only run into it trying to investigate SR-9711.

dmcyk commented 5 years ago

@jckarter since, as you said, this isn't meant to be used, should I close this ticket?