Files
swift-mirror/test/Generics/sr13884.swift
Slava Pestov bcee54b936 GSB: The combination of a superclass and conformance requirement might force a type to be concrete
A protocol can constrain an associated type to Self:

    protocol P {
      associatedtype A : Q where A.B == Self
    }

    protocol Q {
      associatedtype B
    }

And a class might conform to this protocol:

    class C : P {
      typealias A = D
    }

    class D : Q {
      typealias B = C
    }

The generic signature <Self where Self : P, Self : C> is built during
conformance checking. Since Self : C, we must have that Self.A == D;
since D.B == C, the requierement 'A.B == Self' in protocol P implies
that 'Self == C'. So the correct minimized signature here is
<Self where Self == C>.

This wasn't handled properly before, because of assumptions in
removeSelfDerived() and a couple of other places.

Fixes rdar://71677712, rdar://76155506, https://bugs.swift.org/browse/SR-10033,
https://bugs.swift.org/browse/SR-13884.
2021-04-03 23:04:39 -04:00

35 lines
1.1 KiB
Swift

// RUN: %target-typecheck-verify-swift
// RUN: %target-swift-frontend -emit-ir -debug-generic-signatures %s 2>&1 | %FileCheck %s
public protocol P {
associatedtype A : Q where A.B == Self
}
public protocol Q {
associatedtype B
}
public class C : P {
public typealias A = D
}
public class D : Q {
public typealias B = C
}
// Both <T : P & C> and <T : C & P> minimize to <T where T == C>:
// - T : P and T : C imply that T.A == C.A == D;
// - T : P also implies that T.A.B == T, via A.B == Self in P;
// - Since T.A == D, T.A.B == D.B, therefore Self == D.B.
// - D.B is a typealias for C, so really Self == C.
// CHECK-LABEL: Generic signature: <T where T == D.B>
public func takesBoth1<T : P & C>(_: T) {}
// expected-warning@-1 {{redundant conformance constraint 'T' : 'P'}}
// expected-note@-2 {{conformance constraint 'T' : 'P' implied here}}
// CHECK-LABEL: Generic signature: <U where U == D.B>
public func takesBoth2<U : C & P>(_: U) {}
// expected-warning@-1 {{redundant conformance constraint 'U' : 'P'}}
// expected-note@-2 {{conformance constraint 'U' : 'P' implied here}}