Skip to content

Commit 9cd9f26

Browse files
authored
Merge pull request #14160 from xedin/rdar-36449760-5.0
2 parents 72dec75 + 84f9fcd commit 9cd9f26

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,29 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
954954
return { valueType, valueType };
955955
}
956956

957+
static NominalTypeDecl *getInnermostConformingDC(TypeChecker &TC,
958+
DeclContext *DC,
959+
ProtocolDecl *protocol) {
960+
do {
961+
if (DC->isTypeContext()) {
962+
auto *NTD = DC->getAsNominalTypeOrNominalTypeExtensionContext();
963+
auto type = NTD->getDeclaredType();
964+
965+
ConformanceCheckOptions options;
966+
options |= ConformanceCheckFlags::InExpression;
967+
options |= ConformanceCheckFlags::SuppressDependencyTracking;
968+
options |= ConformanceCheckFlags::SkipConditionalRequirements;
969+
970+
auto result =
971+
TC.conformsToProtocol(type, protocol, NTD->getDeclContext(), options);
972+
973+
if (result)
974+
return NTD;
975+
}
976+
} while ((DC = DC->getParent()));
977+
978+
return nullptr;
979+
}
957980
/// Bind type variables for archetypes that are determined from
958981
/// context.
959982
///
@@ -1015,8 +1038,18 @@ static void bindArchetypesFromContext(
10151038
// parameters, or because this generic parameter was constrained
10161039
// away into a concrete type.
10171040
if (found != replacements.end()) {
1041+
Type contextTy;
1042+
1043+
if (genericEnv) {
1044+
contextTy = genericEnv->mapTypeIntoContext(paramTy);
1045+
} else {
1046+
auto *protocol = parentDC->getAsProtocolOrProtocolExtensionContext();
1047+
auto conformingDC = getInnermostConformingDC(cs.TC, cs.DC, protocol);
1048+
assert(conformingDC);
1049+
contextTy = conformingDC->getDeclaredTypeInContext();
1050+
}
1051+
10181052
auto typeVar = found->second;
1019-
auto contextTy = genericEnv->mapTypeIntoContext(paramTy);
10201053
cs.addConstraint(ConstraintKind::Bind, typeVar, contextTy,
10211054
locatorPtr);
10221055
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: not %target-swift-frontend %s -typecheck
2+
3+
protocol A {
4+
var question: String { get }
5+
6+
struct B {
7+
var answer: Int = 42
8+
9+
func foo(a: A) {
10+
_ = a.question
11+
}
12+
}
13+
}
14+
15+
class C : A {
16+
var question: String = "ultimate question"
17+
18+
func foo() -> B {}
19+
func bar() -> A.B {}
20+
func baz(b: B) {
21+
_ = b.answer
22+
}
23+
}
24+
25+
class D : A {
26+
var question: String = ""
27+
28+
struct E {
29+
func baz(b: B) {
30+
_ = b.answer
31+
}
32+
}
33+
}
34+
35+
class F<T> : A {
36+
var question: String = ""
37+
38+
func foo(b: B) {
39+
_ = b.answer
40+
}
41+
}

0 commit comments

Comments
 (0)