Skip to content

Commit 4392a10

Browse files
authored
Merge pull request #7728 from DougGregor/abstract-conformance-via-existential
2 parents 51d0715 + cbbf415 commit 4392a10

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,32 +1916,35 @@ bool GenericSignatureBuilder::addSameTypeRequirementToConcrete(
19161916
// Make sure the concrete type fulfills the requirements on the archetype.
19171917
// FIXME: Move later...
19181918
DenseMap<ProtocolDecl *, ProtocolConformanceRef> conformances;
1919-
if (!Concrete->is<ArchetypeType>()) {
1920-
CanType depTy = rep->getDependentType({ }, /*allowUnresolved=*/true)
1921-
->getCanonicalType();
1922-
for (auto &conforms : rep->getConformsTo()) {
1923-
auto protocol = conforms.first;
1924-
auto conformance =
1925-
getLookupConformanceFn()(depTy, Concrete,
1926-
protocol->getDeclaredInterfaceType()
1927-
->castTo<ProtocolType>());
1928-
if (!conformance) {
1929-
Diags.diagnose(Source->getLoc(),
1930-
diag::requires_generic_param_same_type_does_not_conform,
1931-
Concrete, protocol->getName());
1932-
return true;
1933-
}
1919+
CanType depTy = rep->getDependentType({ }, /*allowUnresolved=*/true)
1920+
->getCanonicalType();
1921+
for (auto &conforms : rep->getConformsTo()) {
1922+
auto protocol = conforms.first;
1923+
auto conformance =
1924+
getLookupConformanceFn()(depTy, Concrete,
1925+
protocol->getDeclaredInterfaceType()
1926+
->castTo<ProtocolType>());
1927+
if (!conformance) {
1928+
Diags.diagnose(Source->getLoc(),
1929+
diag::requires_generic_param_same_type_does_not_conform,
1930+
Concrete, protocol->getName());
1931+
return true;
1932+
}
19341933

1935-
conformances.insert({protocol, *conformance});
1934+
conformances.insert({protocol, *conformance});
19361935

1937-
// Update the requirement source now that we know it's concrete.
1938-
// FIXME: Bad concrete source info.
1939-
auto concreteSource = Source->viaConcrete(*this,
1940-
conformance->getConcrete());
1941-
updateRequirementSource(conforms.second, concreteSource);
1942-
}
1936+
// Abstract conformances are acceptable for existential types.
1937+
assert(conformance->isConcrete() || Concrete->isExistentialType());
1938+
1939+
// Update the requirement source now that we know it's concrete.
1940+
// FIXME: Bad concrete source info.
1941+
auto concreteSource = Source->viaConcrete(*this,
1942+
conformance->isConcrete()
1943+
? conformance->getConcrete()
1944+
: nullptr);
1945+
updateRequirementSource(conforms.second, concreteSource);
19431946
}
1944-
1947+
19451948
// Record the requirement.
19461949
rep->ConcreteType = Concrete;
19471950

test/Generics/requirement_inference.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,20 @@ struct X11<T: P12, U: P12> where T.B == U.B.A {
230230
// CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 : P12, τ_0_1 == X10, τ_0_0.B == X10>
231231
func upperSameTypeConstraint<V>(_: V) where U == X10 { }
232232
}
233+
234+
#if _runtime(_ObjC)
235+
// rdar://problem/30610428
236+
@objc protocol P14 { }
237+
238+
class X12<S: AnyObject> {
239+
func bar<V>(v: V) where S == P14 {
240+
}
241+
}
242+
243+
@objc protocol P15: P14 { }
244+
245+
class X13<S: P14> {
246+
func bar<V>(v: V) where S == P15 {
247+
}
248+
}
249+
#endif

0 commit comments

Comments
 (0)