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-8451] Swift's optional lifting/promotion is overzealous #50972

Closed
weissi opened this issue Aug 2, 2018 · 0 comments
Closed

[SR-8451] Swift's optional lifting/promotion is overzealous #50972

weissi opened this issue Aug 2, 2018 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@weissi
Copy link
Member

weissi commented Aug 2, 2018

Previous ID SR-8451
Radar None
Original Reporter @weissi
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

Environment
  • swift 4.1 & recent swift 4.2 snapshots on Mac and Linux.
Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee None
Priority Medium

md5: de349cbb62f36144fa9ce492b73e96f1

duplicates:

  • SR-2176 Add warning for ambiguous enum value assignment

Issue Description:

Here's a Swift bug that was hiding a real SwiftNIO bug:

struct SelectorEventSet: OptionSet, Equatable {
    typealias RawValue = UInt8

    let rawValue: RawValue

    static let _none = SelectorEventSet(rawValue: 0)
    static let reset = SelectorEventSet(rawValue: 1 << 0)
    static let readEOF = SelectorEventSet(rawValue: 1 << 1)
    static let read = SelectorEventSet(rawValue: 1 << 2)
    static let write = SelectorEventSet(rawValue: 1 << 3)

    init(rawValue: SelectorEventSet.RawValue) {
        self.rawValue = rawValue
    }
}

func test(_ ev: SelectorEventSet) {
    guard ev != .none else { // note how I "forgot" the underscore in front of `._none`
        return
    }
    print("not none")
}

test(._none)

in the line

    guard ev != .none else {

we're comparing ev which is a non-optional❗ SelectorEventSet to .none. I meant to write ._none and the compiler didn't complain at all. .none is the one from Optional.none. So even though ev is non-optional so will never fall into the guard else branch after being lifted to an optional, the Swift compiler lifts ev which is of type SelectorEventSet to Optional<SelectorEventSet>.some(ev) and then compares that to Optional<SelectorEventSet.none (which will never be the same).

Arguably the compiler should not do the optional promotion here because the other side is non-optional and should error. At the very least it should warn that my guard ev != .none doesn't make any sense because it can't hit the else branch.

@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.
Projects
None yet
Development

No branches or pull requests

1 participant