Swift @autoclosure 评估受类型注释的影响? (编译器错误?)

标签 swift typechecking compiler-bug

我今天又开始玩 Swift 并且需要一个 undefined()功能。基本上,一个函数可以是您想要的任何类型,但在实际运行/评估时会崩溃。如果您还没有时间实现某个表达式但想查看程序类型是否检查,这将很有用。

我还实现了一个 Result<T>和一个(有问题的)函数 chain返回左边的 Result<>如果不成功,否则对Result<> .因此,签名为chain<L,R>(l : Result<L>, r : @autoclosure () -> Result<R>) -> Result<R>。 .我定义对了Result<>作为@autoclosure因为当且仅当左侧失败时才无需对其进行评估。

我对这些的有用性(或改进)不感兴趣,我只对为什么我的程序在标记为 [L3] 的行崩溃感兴趣。 .

请注意

  • 符合预期[L1]工作正常(|| 是惰性评估)
  • [L2]工作正常(chain 在其正确的论点中也很懒惰)

但是,奇怪的是

  • [L3]使评估 undefined() 的程序崩溃

根据我的理解,L2 和 L3 在运行时应该是等价的:L3 只是告诉类型检查器一些它已经知道的事情......顺便说一下,如果你改变 undefined 的类型,同样的效果也会发生。至 () -> Result<T> (而不是 () -> T ),那么即使没有 as Result<String> 也能正常工作.

这是我的全部代码:

import Foundation

enum Result<T> {
    case Success(@autoclosure () -> T);
    case Failure(@autoclosure () -> NSError)
}

func undefined<T>(file:StaticString=__FILE__, line:UWord=__LINE__) -> T {
    fatalError("undefined", file:file, line:line)
}

func chain<L,R>(l : Result<L>, r : @autoclosure () -> Result<R>) -> Result<R> {
    switch(l) {
    case .Failure(let f):
        return .Failure(f())
    case .Success(let _):
        return r()
    }
}

func testEvaluation() {
    let error = NSError(domain: NSPOSIXErrorDomain, code: Int(ENOENT), userInfo: nil)
    let failure : Result<String> = .Failure(error)
    assert(true || undefined() as Bool) // [L1]: works
    let x : Result<String> = chain(failure, undefined() as Result<String>) // [L2]: works
    print("x = \(x)\n")
    let y : Result<String> = chain(failure, undefined()) // [L3]: CRASHES THE PROGRAM EVALUATING undefined()
    print("y = \(y)\n")
}

testEvaluation()

信不信由你,程序的输出是:

x = (Enum Value)
fatal error: undefined: file main.swift, line 27
Illegal instruction: 4

这不对!为什么 as Result<String> (这是 L2 和 L3 之间唯一的区别)改变程序的输出?这应该完全在类型检查器中处理,这意味着在编译时,不是吗?编译器错误?

重现此内容的最快方法应该是:

  1. 将我所有的代码复制到剪贴板
  2. cd /tmp
  3. pbpaste > main.swift
  4. xcrun -sdk macosx swiftc main.swift
  5. ./main

实际输出:

x = (Enum Value)
fatal error: undefined: file main.swift, line 27
Illegal instruction: 4

预期输出:

x = (Enum Value)
y = (Enum Value)

最佳答案

已被 Swift 开发人员 Joe Groff 确认为错误 via Twitter .

关于Swift @autoclosure 评估受类型注释的影响? (编译器错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28004126/

相关文章:

swift - 从模态视图转到选项卡栏 View Controller 并且不会丢失选项卡栏

ios - 使用ios swift取消订阅附近的api后如何禁用蓝牙?

ios - iOS应用程序在Xcode控制台以外的地方记录日志

Swift/SpriteKit 碰撞检测

javascript - 如何在 Javascript 中检查一个值是否是整数(特殊情况 1.0 应该是 float )

c++ - 您可以在第二个声明中使用 `= delete` 模板函数吗?

c - 具有指定初始化程序的 MSVC12 (VS2013) 中可能存在编译器错误

performance - 检查 Perl 函数参数值得吗?

haskell - "Type variable is ambiguous"在 Haskell Yesod 中持久化

c++ - 使用 typealias 代替定义中类中定义的 typedef