swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.49k stars 10.35k forks source link

[SR-8319] Default associated type is ignored #50847

Open swift-ci opened 6 years ago

swift-ci commented 6 years ago
Previous ID SR-8319
Radar None
Original Reporter Anandabits (JIRA User)
Type Bug
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | @DougGregor | |Priority | Medium | md5: 13c0eb9af526bf35df63c6c3e250b84a

Issue Description:

The code below is the same as in SR-8308. That ticket is focused on the compiler crash. This ticket is focused on the need to define `typealias B = _A` in `struct _A` where the associated type is already defaulted to `Self`. This ticket should also focus on the need to define that default explicitly despite the `where B == Self` constraint in the declaration of `P2`.

protocol P1 {
    associatedtype B: P1
}
protocol P2: P1 where B == Self {
    // isn't this redunant with the B == Self constraint?
    // if it is removed the code won't compile but it seems like it should be unnecessary
    associatedtype B = Self
}
protocol P3 {
    associatedtype T: P1
    associatedtype U
    var s: S<T, U> { get }
}
protocol P4: P3 where T: P3, T.B == T.T.B {
    typealias T2 = T.T
    typealias U2 = T.U
}
struct S<T: P1, U>: P1, P3 {
    typealias B = T.B
    var s: S<T, U> { return self }
    func f<F: P3>(_ type: F.Type) -> F where F.T == T, F.U == U {
        // the body doesn't matter
        fatalError()
    }
}
extension S: P4 where T: P3, T.B == T.T.B {}
struct _A: P2 {
    // if this is removed the code won't compile but it seems like it should be unnecessary
    // the associated type is defaulted *and* constrained to be Self
    typealias B = _A
}
struct A<X, Y>: P4 {
    var s: S<S<_A, X>, Y> { return S() }
}
// if the extension that crashes is commented out and replaced with the other variant the
// "Same-type constraint 'T' == 'S<_A, T.U>' is recursive" error is produced
// it seems like this should be valid code.
// extension S where T == S<_A, U2> {
extension S where T.B == _A {
    var A: A<U2, U> {
        return f(A<U2, U>.self)
    }
}
belkadan commented 6 years ago

Another for @DougGregor's associated type inference rework.