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-7222] Accessing Dictionary from rawValue in enum causes runtime crash in Swift 4.1. #49770

Open
swift-ci opened this issue Mar 18, 2018 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software regression run-time crash Bug → crash: Swift code crashed during execution standard library Area: Standard library umbrella swift 4.1

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-7222
Radar rdar://problem/38624846
Original Reporter valleyman86 (JIRA User)
Type Bug
Environment

Xcode 9.3 beta 4 Swift 4.1

Additional Detail from JIRA
Votes 0
Component/s Compiler, Standard Library
Labels Bug, 4.1Regression, RunTimeCrash
Assignee None
Priority Medium

md5: 8861114e1b1eac9fc303c01bd4786968

Issue Description:

enum PlaydoughConfigView {
    case header
    case subtitle
    case art
    case progress
    case controls
    case bannerAds
}

enum PlaydoughConfig {
    case standard
    case basic
    case compactStandard
    case compactBasic
}

extension PlaydoughConfig: RawRepresentable {
    typealias RawValue = [PlaydoughConfigView]

    static let configs = [.standard: [.header, .art, .subtitle, .progress, .controls, .bannerAds],
                          .basic: [.header, .art, .subtitle, .progress, .controls],
                          .compactStandard: [.header, .art, .progress, .controls, .bannerAds],
                          .compactBasic: [.header, .art, .progress, .controls]] as [PlaydoughConfig: RawValue]

    init?(rawValue: RawValue) {
        if let key = PlaydoughConfig.configs.first(where: { rawValue == $1 })?.key {
            self = key
        }
        return nil
    }



    var rawValue: RawValue {
        return PlaydoughConfig.configs[self] ?? []
    }
}

let test = PlaydoughConfig.configs[.standard] // Crash

This is a regression from Swift 4.0. It seems the Dictionary.init is calling rawValue most likely due to equatable. This code works fine in 4.0 and crashes in 4.1.

@belkadan
Copy link
Contributor

@swift-ci create

@airspeedswift
Copy link
Member

Reduced to this, which runs OK on 4.0 but recurses infinitely at the == inside rawValue:

enum E {
  case a
}

extension E: RawRepresentable {
  typealias RawValue = [Int]

  init?(rawValue: RawValue) {
    return nil
  }

  var rawValue: RawValue {
    _ = self == .a
    return []
  }
}

E.a == E.a

The reason being, raw representable things have a default implementation of == that uses the raw values when the raw values are Equatable, and it's calling itself through that.

This also recursed infinitely in 4.0 if you used an Int or String as your raw representation. It's only arrays (or dictionaries...) that avoided this in 4.0. But since they are now Equatable too, they have the same problem.

@swift-ci
Copy link
Collaborator Author

Comment by Joseph Gentry (JIRA)

Thanks for the reduction. This explains why my initial example failed in both 4.0 and 4.1 (I did not use an array).

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
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 crash Bug: A crash, i.e., an abnormal termination of software regression run-time crash Bug → crash: Swift code crashed during execution standard library Area: Standard library umbrella swift 4.1
Projects
None yet
Development

No branches or pull requests

4 participants