Skip to content

Commit 0254c0e

Browse files
committed
RequirementMachine: Fix handling of unavailable Sendable conformances in concretizeNestedTypesFromConcreteParent()
We can't just ignore unavailable conformances because the generic signature we're computing might itself be attached to an unavailable declaration. Until we get a proper fix, only drop unavailable conformances to Sendable here. Fixes rdar://problem/94305457.
1 parent 9e1a293 commit 0254c0e

File tree

5 files changed

+43
-22
lines changed

5 files changed

+43
-22
lines changed

lib/AST/RequirementMachine/ConcreteTypeWitness.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,13 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
153153
// subclasses of 'C' which are 'Sendable'.
154154
bool allowMissing = (requirementKind == RequirementKind::SameType);
155155

156+
bool allowUnavailable =
157+
!proto->isSpecificProtocol(KnownProtocolKind::Sendable);
156158
auto conformance = module->lookupConformance(concreteType,
157159
const_cast<ProtocolDecl *>(proto),
158-
allowMissing);
159-
if (conformance.isInvalid() || conformance.hasUnavailableConformance()) {
160+
allowMissing,
161+
allowUnavailable);
162+
if (conformance.isInvalid()) {
160163
// For superclass rules, it is totally fine to have a signature like:
161164
//
162165
// protocol P {}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol P { }
4+
5+
struct X { }
6+
7+
@available(*, unavailable)
8+
extension X: P { }
9+
10+
struct Y<T: P> { }
11+
12+
@available(*, unavailable)
13+
extension Y {
14+
// Okay, because the unavailable conformance is used within an
15+
// unavailable context.
16+
init() where T == X { }
17+
}
18+
19+
// A more elaborate setup that hits the conformance check in property map
20+
// construction rather than concrete contraction.
21+
22+
protocol AssocP {}
23+
24+
@available(*, unavailable)
25+
struct ConcreteP {}
26+
27+
@available(*, unavailable)
28+
extension ConcreteP: AssocP {}
29+
30+
protocol Base {
31+
associatedtype T : AssocP
32+
}
33+
34+
@available(*, unavailable)
35+
extension Base where T == ConcreteP {}

test/decl/protocol/req/recursion.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protocol PI {
7373
}
7474

7575
struct SI<A: PI> : I where A : I, A.T == SI<A> {
76-
// expected-error@-1 5{{generic struct 'SI' has self-referential generic requirements}}
76+
// expected-error@-1 3{{generic struct 'SI' has self-referential generic requirements}}
7777
func ggg<T : I>(t: T.Type) -> T {
7878
return T()
7979
}
@@ -104,5 +104,5 @@ struct SU<A: P> where A.T == SU {
104104
}
105105

106106
struct SIU<A: PI> : I where A : I, A.T == SIU {
107-
// expected-error@-1 5{{generic struct 'SIU' has self-referential generic requirements}}
107+
// expected-error@-1 3{{generic struct 'SIU' has self-referential generic requirements}}
108108
}

test/decl/protocol/unavailable.swift

Lines changed: 0 additions & 17 deletions
This file was deleted.

validation-test/compiler_crashers_2_fixed/0161-sr6569.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ protocol P {
66

77
struct Type<Param> {}
88
extension Type: P where Param: P, Param.A == Type<Param> {
9-
// expected-error@-1 8{{extension of generic struct 'Type' has self-referential generic requirements}}
9+
// expected-error@-1 6{{extension of generic struct 'Type' has self-referential generic requirements}}
1010
// expected-note@-2 6{{through reference here}}
1111
// expected-error@-3 {{type 'Type<Param>' does not conform to protocol 'P'}}
1212
typealias A = Param

0 commit comments

Comments
 (0)