Baoshan
(Baoshan Sheng)
1
Below 40 lines of code compiles and executes correctly:
protocol Protocol {
associatedtype ElementValue: Singular
static var isArray: Bool { get }
}
protocol Singular: Equatable, NonOptional {
associatedtype ElementValue = Self
}
extension Singular {
static var isArray: Bool { false }
public static func == (lhs: Self, rhs: Self) -> Bool {
fatalError()
}
}
protocol NonOptional: Protocol {
associatedtype ElementValue = Self
}
extension Optional: Protocol where Wrapped: NonOptional {
typealias ElementValue = Wrapped.ElementValue
static var isArray: Bool { Wrapped.isArray }
}
@propertyWrapper struct Wrapper <T: Protocol> {
var wrappedValue: T { fatalError() }
var isArray: Bool { T.isArray }
}
struct Property: Singular {
var value: Int
}
struct Struct {
@Wrapper() var property: Property?
var isArray: Bool { _property.isArray }
}
assert(Struct().isArray == false)
If we move below 4 lines into a separate file (e.g., Struct.swift), the program compiles okay but traps at runtime.
struct Struct {
@Wrapper() var property: Property?
var isArray: Bool { _property.isArray }
}
I am unable to further nail down the true culprit. Actually I am not sure if the reproduction is minimal (it’s very possible to be minimal – even removing the Equatable covers the bug) 
Could someone help?
Baoshan
(Baoshan Sheng)
2
I removed the @propertyWrapper part, the issue is still there:
-- Struct.swift --
struct Struct {
var property = Wrapper<Property?>()
var isArray: Bool { property.isArray }
}
-- main.swift --
protocol Protocol {
associatedtype ElementValue: Singular
static var isArray: Bool { get }
}
protocol Singular: Equatable, NonOptional {
associatedtype ElementValue = Self
}
extension Singular {
static var isArray: Bool { false }
public static func == (lhs: Self, rhs: Self) -> Bool {
fatalError()
}
}
protocol NonOptional: Protocol {
associatedtype ElementValue = Self
}
extension Optional: Protocol where Wrapped: NonOptional {
typealias ElementValue = Wrapped.ElementValue
static var isArray: Bool { Wrapped.isArray }
}
struct Wrapper <T: Protocol> {
var wrappedValue: T { fatalError() }
var isArray: Bool { T.isArray }
}
struct Property {
var value: Int
}
extension Property: Singular { }
assert(Struct().isArray == false)
Program still crashes at runtime. If we perform any of the below actions, the program executes as expected:
- Combine the source code into one single file (move
Struct definition either to the top or bottom of main.swift).
- Remove
Equatable
- Remove
ElementValue typealias & associatedtype
When the compilation mode is set to whole module instead of incremental, the program executes as expected, may this be the real culprit?
I’ve filed a bug report. Please correct me if there’s something wrong on my side.