Skip to content

Commit 02d2b4a

Browse files
committed
[IDE] Use LookUpConformanceInModule for synthesized extension requirement substitution
The extension may have requirements stating new conformance requirements that aren't present in the underlying substitution map for the conforming type. rdar://152164768
1 parent a868d92 commit 02d2b4a

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

lib/IDE/IDETypeChecking.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,11 @@ struct SynthesizedExtensionAnalyzer::Implementation {
339339

340340
if (!BaseType->isExistentialType()) {
341341
// Apply any substitutions we need to map the requirements from a
342-
// a protocol extension to an extension on the conforming type.
343-
Req = Req.subst(subMap);
342+
// a protocol extension to an extension on the conforming type. We
343+
// need to lookup conformances outside of the substitution map since
344+
// the extension may introduce new conformance constraints.
345+
Req = Req.subst(QuerySubstitutionMap{subMap},
346+
LookUpConformanceInModule());
344347
if (Req.hasError()) {
345348
// Substitution with interface type bases can only fail
346349
// if a concrete type fails to conform to a protocol.
@@ -353,6 +356,14 @@ struct SynthesizedExtensionAnalyzer::Implementation {
353356
if (Req.getKind() != RequirementKind::Layout)
354357
assert(!Req.getSecondType()->hasArchetype());
355358

359+
// FIXME: This doesn't correctly handle conformance requirements, e.g:
360+
//
361+
// extension P where X: Q, X.Y == Int {}
362+
//
363+
// Since the archetype we have for `X` doesn't necessarily have a
364+
// conformance to `Q` in the conforming type's generic environment. This
365+
// results in a substitution failure for `X.Y`.
366+
// https://github.com/swiftlang/swift/issues/83564
356367
auto *env = Target->getGenericEnvironment();
357368
SmallVector<Requirement, 2> subReqs;
358369
subReqs.push_back(

test/IDE/print_synthesized_extensions_generics.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,21 @@ extension G : P2 {}
8585
// CHECK: extension P2 where Self.T.T : print_synthesized_extensions_generics.A {
8686
// CHECK-NEXT: func blah()
8787
// CHECK-NEXT: }
88+
89+
public protocol P3 {
90+
associatedtype A
91+
}
92+
public protocol P4 {
93+
associatedtype B: P3
94+
}
95+
96+
public struct S1<A> {}
97+
98+
// Make sure we don't crash. Unfortunately we don't yet correctly output these
99+
// though.
100+
extension S1: P4 where A: P4, A.B.A == A {
101+
public typealias B = A.B
102+
}
103+
extension P3 where A: P4, A.B.A == A {
104+
public func foo() {}
105+
}

0 commit comments

Comments
 (0)