Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-7655] Double(exactly:) and Float(exactly:) can throw fatal errors when called with Self from a protocol extension #50196

Closed
kmahar opened this issue May 10, 2018 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella

Comments

@kmahar
Copy link

kmahar commented May 10, 2018

Previous ID SR-7655
Radar None
Original Reporter @kmahar
Type Bug
Status Resolved
Resolution Done
Environment

Swift 4.1 on MacOS

Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)

Target: x86_64-apple-darwin17.4.0

Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Bug
Assignee None
Priority Medium

md5: 14461ce54f485ab1b622a72123886a21

Issue Description:

I ran into some unexpected fatal errors writing code to convert between different number types.

A much simplified example to reproduce this:

protocol A {
    init?(fromInt: Int)
    init?<T: BinaryInteger>(exactly source: T)
}

extension Float: A {}
extension Double: A {}

extension A {
    init?(fromInt int: Int) {
        if let exact = Self(exactly: int) {
            self = exact
            return
        }
        return nil
    }
}

// these are fine
let float1 = Float(exactly: 1)
let double1 = Double(exactly: 1)

// these give fatal errors
let float2 = Float(fromInt: 1)
let double2 = Double(fromInt: 1)

The output is

Fatal error: file /BuildRoot/Library/Caches/com.apple.xbs/Binaries/swiftlang/install/TempContent/Objects/BNI_assert_lightweight/swift-macosx-x86_64/stdlib/public/core/8/FloatingPointTypes.swift, line 1279
Exited with signal code 4

If I move the same exact code into Float and Double extensions like this, rather than using the default implementation for protocol A:

extension Float: A {
    init?(fromInt int: Int) {
        if let exact = Float(exactly: int) {
            self = exact
            return
        }
        return nil
    }
}

extension Double: A {
    init?(fromInt int: Int) {
        if let exact = Double(exactly: int) {
            self = exact
            return
        }
        return nil
    }
}

it works perfectly.

If I extend Int, Int32, Int64 to conform to A, the protocol default impl works perfectly for them; the issue seems to just be with floating point types.

Since the error is coming from generated code I wasn't sure how to dig further into what exactly is going on inside Swift here, but it seems incorrect that the protocol default implementation with Self is doing something different.

Let me know what you think - thanks!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

1 participant