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-13446] Optional<IndexPath>.none != nil #55888

Closed
swift-ci opened this issue Aug 25, 2020 · 4 comments
Closed

[SR-13446] Optional<IndexPath>.none != nil #55888

swift-ci opened this issue Aug 25, 2020 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-13446
Radar rdar://67750739
Original Reporter sadlerjw (JIRA User)
Type Bug
Status Closed
Resolution Duplicate
Environment

Xcode Version 11.5 (11E608c)

(Using Swift 5 for SWIFT_VERSION)

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

md5: 9dd067e7ef11417416e33ca27ac79e79

duplicates:

  • SR-11593 REPL incorrectly reports URL as nil

Issue Description:

The expression Optional<IndexPath>.none == nil evaluates to false.
It seems that an IndexPath? variable set to nil is interpreted as an IndexPath with a single index that evaluates to 0. (That's what prints with po in the Xcode debugger)

(Apologies if this is the wrong place to file this bug...I wasn't sure whether it was a Swift issue or an Apple issue. I've also filed a Feedback with Apple: FB8534137)

@poya
Copy link
Contributor

poya commented Aug 28, 2020

Testing the claims from the bug report in the REPL in Xcode 11.5

// > swift
Welcome to Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53).
Type :help for assistance.
  1> import Foundation
  2> Optional<IndexPath>.none == nil
$R0: Bool = true
  3> let indexPath: IndexPath? = nil
indexPath: IndexPath? = nil
  4> dump(indexPath)
- nil
$R1: IndexPath? = nil

While the above doesn't seem to correspond to the behavior reported, perhaps what you are seeing is the LLDB bug SR-11593, where the debugger incorrectly displays nil for some Optionals? (see screenshot in SR-11546 for example)

@swift-ci
Copy link
Collaborator Author

Comment by Jason Sadler (JIRA)

Thanks for looking into this! I think a few things must be at play here.

  1. I used the REPL and I'm seeing what you're seeing, so no bug there.

  2. Using po in LLDB to find the value of the variable does sound exactly like SR-11593.

  3. However, in my project, I am still getting incorrect behaviour with a conditional when running on the iPad simulator:

let selectedProjectIsInList = listViewController.selectedObject.map { dataSource.indexPath(for: $0) } != Optional<IndexPath>.none
if !selectedProjectIsInList {
    listViewController.selectObject(nil)
    router.emptyRightPane()
}

where selectedObject is an optional, and indexPath(for🙂 returns IndexPath?. If I use nil instead of Optional<IndexPath>.none above, the code within the if block is never run. Switching it to use Optional<IndexPath>.none causes it to behave as expected. indexPath(for🙂 is a thin wrapper around an NSFetchedResultsController:

func indexPath(for object: T) -> IndexPath? {
    return fetchedResultsController.indexPath(forObject: object)
}

@poya
Copy link
Contributor

poya commented Aug 29, 2020

The Optional map function looks like this:

func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?

It means that in your case it will return IndexPath?? i.e. Optional<Optional<IndexPath>>.

You have 3 potential returns for your expression

  1. selectedObject is nil returns

    Optional<Optional<IndexPath>>.none
    
  2. selectedObject is not nil and
    2.1 has no indexPath returns

    Optional<Optional<IndexPath>>.some(Optional<IndexPath>.none)
    

    2.2 has indexPath returns

    Optional<Optional<IndexPath>>.some(Optional<IndexPath>.some(IndexPath))
    

    If you compare these returns for equality to nil, you'll see that it's only true for (1), but if you instead compare with Optional<IndexPath>.none it's only true for (2.1).

To fix your problem you probably want to replace map with flatMap to get an expression that returns IndexPath?.

@swift-ci
Copy link
Collaborator Author

Comment by Jason Sadler (JIRA)

�‍♂️ yes. I can’t believe I missed that. Thanks so much!
I suppose this can be resolved as a dupe of the issue you mentioned in your first comment.

@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

2 participants