Navigation Menu

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-2559] EXC_BAD_ACCESS when comparing two optionals #45164

Closed
swift-ci opened this issue Sep 4, 2016 · 7 comments
Closed

[SR-2559] EXC_BAD_ACCESS when comparing two optionals #45164

swift-ci opened this issue Sep 4, 2016 · 7 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Sep 4, 2016

Previous ID SR-2559
Radar None
Original Reporter simplgy (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Version 8.0 beta 5 (8S193k)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee @CodaFi
Priority Medium

md5: 3347db583ab3a5058e6686a7c2f8a53b

relates to:

  • SR-626 No diagnostic for unconditional recursion

Issue Description:

I have a reproducible crash in playground environment.
The formatting here is bad, so you can see the code here: https://gist.github.com/SimplGy/934af7b6bd43b1296a4fa168fd2137bc

Or it is below for completeness.

No Runtime Error:

func == (l: Car, r: Car) -> Bool { return l.vin == r.vin }
struct Car { let vin: String }
protocol hasDriversLicense: class {
  var car: Car? { get set }
}
class YoungPro: hasDriversLicense {
  var car: Car? { didSet {
    if let oldValue = oldValue, car = car, oldValue == car { return }
    print("car changed")
  }}
  init(){}
}
let you = YoungPro()
you.car = Car(vin: "abc123")

Runtime error:

func == (l: Car?, r: Car?) -> Bool {
  if l == nil && r == nil { return true }
  guard let l = l, let r = r else { return false }
  return l.vin == r.vin
}
struct Car { let vin: String } // class, struct, tuple... doesn't matter

protocol hasDriversLicense: class {
  var car: Car? { get set }
}

class YoungPro: hasDriversLicense {
  var car: Car? { didSet {
    if oldValue == car { return }
    print("car changed")
  }}
  init(){}
}

let you = YoungPro()
you.car = Car(vin: "abc123") // EXC_BAD_ACCESS code: 2
@belkadan
Copy link
Contributor

belkadan commented Sep 6, 2016

The == nil is just calling the same function over again, rather than using the == in the standard library for comparing to nil. I'm not sure I'd even call this incorrect behavior, but it certainly isn't useful. @rudkx, what do you think?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Sep 7, 2016

Comment by Eric (JIRA)

Oh! Of course. I'm sure there's a way to check for nil without using `== nil` but that didn't even occur to me.

@belkadan
Copy link
Contributor

belkadan commented Sep 7, 2016

A related enhancement request here would be something like Clang's -Winfinite-recursion: we have a call to the containing function here that happens on all paths.

@belkadan
Copy link
Contributor

belkadan commented Sep 7, 2016

You can check for nil by using if case nil = l, or by using a switch. Both of those are a little uglier, though, so I still wonder if we should come up with a better answer.

@rudkx
Copy link
Member

rudkx commented Sep 12, 2016

Generally the "right" way to implement this is to make Car conform to Equatable, define the "func ==" for Cars, and then for optionals let the generic form of "func ==" for optionals of Equatables kick in.

I think a warning like -Winfinite-recursion would be a fine idea, though.

@swift-ci
Copy link
Collaborator Author

Comment by Eric (JIRA)

Yeah, that would work great Mark. I stumbled on this because I was trying to implement this for a `typealias` on a tuple, so I (didn't think I could) make it conform to Equatable. Didn't want to include that complexity in the example though.

@CodaFi
Copy link
Member

CodaFi commented Feb 27, 2018

Resolved by the merge of #11869.

@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. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

4 participants