Swift编译器挂起(可能是泛型参数的类型推断)

时间:2016-06-07 08:06:07

标签: swift compiler-errors functional-programming type-inference

我最近编写了一个函数和一些相关代码,它们充当一种切换表达式(按预期工作)和posted it on CodeReview.SE

我已经开始尝试改进自己的代码并且似乎已经碰壁了,因为看起来我的代码会使操场挂起并且在放入项目时也不会编译。但是,当在项目中输入所有内容时,Xcode不会抱怨,直到我真正尝试构建它。这就是我所拥有的:

func caze<T: Equatable, R>(vals: T..., @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
    return (AnySequence(vals), f)
}

func caze<T, R where T: Equatable, T: ForwardIndexType>(range: Range<T>, @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
    return (AnySequence(range), f)
}


func schwitch<T: Equatable, R>(value: T, _ cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) rethrows -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return try def()
}

func test() {
    schwitch(5,
         caze(0, ret: "hello"),
         caze(1, 2, ret: "test"),
         caze(3..<7, ret: "lol"),
         def: "nop")

    schwitch("helloo",
        caze("hello", "Hello", ret: "test"),
        def: "nop")
}

这是我在尝试构建项目时遇到的错误:

  

命令因信号失败:分段错误:11

堆栈跟踪:

0  swift                    0x000000010c7f366b llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 43
1  swift                    0x000000010c7f2956 llvm::sys::RunSignalHandlers() + 70
2  swift                    0x000000010c7f3ccf SignalHandler(int) + 287
3  libsystem_platform.dylib 0x00007fff87f0752a _sigtramp + 26
4  libsystem_platform.dylib 0x00007f82f4bf0418 _sigtramp + 1825476360
5  swift                    0x000000010ab9e994 (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 52
6  swift                    0x000000010ab9ea2b (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 203
7  swift                    0x000000010ab9f02a (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 1738
8  swift                    0x000000010ab9e56c (anonymous namespace)::ApplyClassifier::classifyApply(swift::ApplyExpr*) + 652
9  swift                    0x000000010ab9dc86 (anonymous namespace)::ErrorHandlingWalker<(anonymous namespace)::CheckErrorCoverage>::walkToExprPre(swift::Expr*) + 278
10 swift                    0x000000010ac45854 swift::ASTVisitor<(anonymous namespace)::Traversal, swift::Expr*, swift::Stmt*, bool, swift::Pattern*, bool, void>::visit(swift::Stmt*) + 148
11 swift                    0x000000010ac42ef7 swift::Stmt::walk(swift::ASTWalker&) + 87
12 swift                    0x000000010ab9d9d5 swift::TypeChecker::checkFunctionErrorHandling(swift::AbstractFunctionDecl*) + 405
13 swift                    0x000000010ab7ef1b typeCheckFunctionsAndExternalDecls(swift::TypeChecker&) + 1451
14 swift                    0x000000010ab7f665 swift::performTypeChecking(swift::SourceFile&, swift::TopLevelContext&, swift::OptionSet<swift::TypeCheckingFlags, unsigned int>, unsigned int) + 1765
15 swift                    0x000000010aa00eb4 swift::CompilerInstance::performSema() + 4580
16 swift                    0x000000010a543596 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&) + 934
17 swift                    0x000000010a54268d frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 2781
18 swift                    0x000000010a53e0ac main + 1932
19 libdyld.dylib            0x00007fff912a35ad start + 1

问题似乎是使用该功能,因为如果我遗漏那部分,一切编译都很好。仅使用caze似乎也可以正常工作,因为以下工作也可以正常工作:

caze(5, ret: "hello")
let test: (AnySequence<Int>, () -> String) = caze(0...5, ret: "hello") // Swift needs some help figuring out which function to use here

这只是Swift编译器中的一个错误,还是我遗漏了什么?

1 个答案:

答案 0 :(得分:1)

首先:正如布莱恩已经说过的那样,它肯定是一个编译器错误,应该从不崩溃。

解决问题:根本原因似乎是rethrows,因为使用以下编译并运行没有任何问题。这与堆栈跟踪5 - 7 classifyRethrowsArgument匹配。

func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () -> R) -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return def()
}

同样适用于

func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) -> R {
    for (vals, f) in cases {
        if vals.contains(value) {
            return f()
        }
    }
    return try! def()
}

我知道这个事实远非一个完整的答案,但我想至少给出一些我发现的暗示。如果您不需要默认情况下能够抛出此代码应该适合您。我将试图弄清楚rethrows导致问题的原因。

swift编译器的TypeCheckError.cpp可能有助于解决这个问题。