Skip to content

Commit 1f7d52d

Browse files
authored
Merge pull request #41801 from slavapestov/rqm-fix-rdar90219229
RequirementMachine: Hack to allow protocol typealiases to appear in associated type inheritance clauses
2 parents fa041e8 + a61f67a commit 1f7d52d

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,10 +504,38 @@ void swift::rewriting::realizeInheritedRequirements(
504504
Type inheritedType
505505
= evaluateOrDefault(ctx.evaluator,
506506
InheritedTypeRequest{decl, index,
507-
TypeResolutionStage::Structural},
507+
TypeResolutionStage::Structural},
508508
Type());
509509
if (!inheritedType) continue;
510510

511+
// The GenericSignatureBuilder allowed an associated type's inheritance
512+
// clause to reference a protocol typealias whose underlying type was a
513+
// protocol or class.
514+
//
515+
// Since protocol typealiases resolve to DependentMemberTypes in
516+
// ::Structural mode, this relied on the GSB's "delayed requirements"
517+
// mechanism.
518+
//
519+
// The RequirementMachine does not have an equivalent, and cannot really
520+
// support that because we need to collect the protocols mentioned on
521+
// the right hand sides of conformance requirements ahead of time.
522+
//
523+
// However, we can support it in simple cases where the typealias is
524+
// defined in the protocol itself and is accessed as a member of 'Self'.
525+
if (auto *assocTypeDecl = dyn_cast<AssociatedTypeDecl>(decl)) {
526+
if (auto memberType = inheritedType->getAs<DependentMemberType>()) {
527+
if (memberType->getBase()->isEqual(
528+
assocTypeDecl->getProtocol()->getSelfInterfaceType())) {
529+
inheritedType
530+
= evaluateOrDefault(ctx.evaluator,
531+
InheritedTypeRequest{decl, index,
532+
TypeResolutionStage::Interface},
533+
Type());
534+
if (!inheritedType) continue;
535+
}
536+
}
537+
}
538+
511539
auto *typeRepr = inheritedTypes[index].getTypeRepr();
512540
SourceLoc loc = (typeRepr ? typeRepr->getStartLoc() : SourceLoc());
513541
if (moduleForInference) {

test/Generics/rdar90219229.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on
2+
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
3+
4+
// CHECK-LABEL: .P@
5+
// CHECK-NEXT: Requirement signature: <Self where Self.[P]T : C>
6+
protocol P {
7+
typealias A = C
8+
9+
associatedtype T : A
10+
}
11+
12+
class C {}
13+
14+
protocol PBad {
15+
typealias A = C
16+
17+
associatedtype B : P
18+
19+
associatedtype T1 : B.A
20+
// expected-error@-1 {{type 'Self.T1' constrained to non-protocol, non-class type 'Self.B.A'}}
21+
22+
associatedtype T2 where T2 : A
23+
// expected-error@-1 {{type 'Self.T2' constrained to non-protocol, non-class type 'Self.A'}}
24+
}
25+
26+
// FIXME: Terrible diagnostics.
27+
28+
protocol PWorse {
29+
// expected-error@-1 2{{circular reference}}
30+
// expected-note@-2 4{{through reference here}}
31+
typealias A = C
32+
33+
associatedtype T : Self.A
34+
// expected-note@-1 2{{while resolving type 'Self.A'}}
35+
// expected-note@-2 2{{through reference here}}
36+
}

validation-test/compiler_crashers_fixed/28839-genericsig.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

88

9-
// RUN: not %target-swift-frontend %s -emit-ir
9+
// RUN: not %target-swift-frontend %s -emit-ir -requirement-machine-protocol-signatures=on
1010
class a{
1111
class a<a:A
1212
protocol A:a{typealias wh:Self.a

0 commit comments

Comments
 (0)