Steps to reproduce:
- Create a new interface builder based iOS app
- Navigate to ViewController.swift
- Paste the following code
import UIKit
protocol P: Hashable {
var name: String { get }
}
extension P {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
enum E: String, P {
case a
var name: String {
rawValue
}
}
struct S: RawRepresentable, P {
let rawValue: String
init?(rawValue: String) {
self.rawValue = rawValue
}
var name: String {
rawValue
}
}
struct SNonRaw: P {
let rawValue: String
init?(rawValue: String) {
self.rawValue = rawValue
}
var name: String {
rawValue
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print("BEFORE NON RAW STRUCT")
let _ = Set<SNonRaw>([SNonRaw(rawValue: "a")!, SNonRaw(rawValue: "a")!, SNonRaw(rawValue: "a")!, SNonRaw(rawValue: "a")!, SNonRaw(rawValue: "a")!])
print("AFTER NON RAW STRUCT")
print("BEFORE STRUCT")
let _ = Set<S>([S(rawValue: "a")!, S(rawValue: "a")!, S(rawValue: "a")!, S(rawValue: "a")!, S(rawValue: "a")!])
print("AFTER STRUCT")
print("BEFORE ENUM")
let _ = Set<E>([.a, .a, .a, .a, .a, .a, .a, .a, .a, .a, .a])
print("AFTER ENUM")
}
}
If you run this on iOS 15.5 simulator you'll get the following console log:
BEFORE NON RAW STRUCT
AFTER NON RAW STRUCT
BEFORE STRUCT
Also, the app hangs. If you stop the app you will get a Problem Report window that gives you the following stacktrace:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libswiftCore.dylib 0x7fff309e094a RawRepresentable<>._rawHashValue(seed:) + 74
1 HashableRawRepresentable 0x109753bd4 protocol witness for Hashable._rawHashValue(seed:) in conformance S + 52
2 HashableRawRepresentable 0x1097539fd S.hash(into:) + 109
3 HashableRawRepresentable 0x109753b91 protocol witness for Hashable.hash(into:) in conformance S + 17
4 libswiftCore.dylib 0x7fff309e0974 RawRepresentable<>._rawHashValue(seed:) + 116
5 HashableRawRepresentable 0x109753bd4 protocol witness for Hashable._rawHashValue(seed:) in conformance S + 52
6 HashableRawRepresentable 0x1097539fd S.hash(into:) + 109
7 HashableRawRepresentable 0x109753b91 protocol witness for Hashable.hash(into:) in conformance S + 17
8 libswiftCore.dylib 0x7fff309e0974 RawRepresentable<>._rawHashValue(seed:) + 116
9 HashableRawRepresentable 0x109753bd4 protocol witness for Hashable._rawHashValue(seed:) in conformance S + 52
10 HashableRawRepresentable 0x1097539fd S.hash(into:) + 109
11 HashableRawRepresentable 0x109753b91 protocol witness for Hashable.hash(into:) in conformance S + 17
12 libswiftCore.dylib 0x7fff309e0974 RawRepresentable<>._rawHashValue(seed:) + 116
13 HashableRawRepresentable 0x109753bd4 protocol witness for Hashable._rawHashValue(seed:) in conformance S + 52
14 HashableRawRepresentable 0x1097539fd S.hash(into:) + 109
15 HashableRawRepresentable 0x109753b91 protocol witness for Hashable.hash(into:) in conformance S + 17
16 libswiftCore.dylib 0x7fff309e0974 RawRepresentable<>._rawHashValue(seed:) + 116
17 HashableRawRepresentable 0x109753bd4 protocol witness for Hashable._rawHashValue(seed:) in conformance S + 52
... (continues forever...)
If you run this on iOS 15.2 simulator everything works and you'll get the following console log:
BEFORE NON RAW STRUCT
AFTER NON RAW STRUCT
BEFORE STRUCT
AFTER STRUCT
BEFORE ENUM
AFTER ENUM
I suspect that this change is responsible for the issue:
https://github.com/apple/swift/pull/39155/commits/f8d72f819ad4f871ce4c72c7ebedb7f479ac92bb
If I basically "revert" this change by adding the following code, the code will run on iOS 15.5 as well:
extension RawRepresentable where RawValue: Hashable, Self: Hashable {
var hashValue: Int {
return rawValue.hashValue
}
}
First post here, so hopefully this has enough information to work with.
If you need any further details, feel free to comment.
Cheers