Skip to content

Commit be791e5

Browse files
committed
[Archetype builder] Check concrete types against superclass constraints.
This was a blatant hole in our checking, admitting ill-formed generic signatures that would crash down the line. Fixes rdar://problem/29288428.
1 parent c73316e commit be791e5

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

lib/AST/ArchetypeBuilder.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,21 @@ bool ArchetypeBuilder::addSuperclassRequirement(PotentialArchetype *T,
988988
});
989989
}
990990

991+
// Make sure the concrete type fulfills the superclass requirement
992+
// of the archetype.
993+
if (T->isConcreteType()) {
994+
Type concrete = T->getConcreteType();
995+
if (!Superclass->isExactSuperclassOf(concrete, getLazyResolver())) {
996+
Diags.diagnose(T->getSameTypeSource().getLoc(),
997+
diag::type_does_not_inherit,
998+
T->getRootParam(), concrete, Superclass)
999+
.highlight(Source.getLoc());
1000+
return true;
1001+
}
1002+
1003+
return false;
1004+
}
1005+
9911006
// Local function to handle the update of superclass conformances
9921007
// when the superclass constraint changes.
9931008
auto updateSuperclassConformances = [&] {
@@ -1273,6 +1288,17 @@ bool ArchetypeBuilder::addSameTypeRequirementToConcrete(
12731288
T->ArchetypeOrConcreteType = NestedType::forConcreteType(Concrete);
12741289
T->SameTypeSource = Source;
12751290

1291+
// Make sure the concrete type fulfills the superclass requirement
1292+
// of the archetype.
1293+
if (T->Superclass) {
1294+
if (!T->Superclass->isExactSuperclassOf(Concrete, getLazyResolver())) {
1295+
Diags.diagnose(Source.getLoc(), diag::type_does_not_inherit,
1296+
T->getRootParam(), Concrete, T->Superclass)
1297+
.highlight(T->SuperclassSource->getLoc());
1298+
return true;
1299+
}
1300+
}
1301+
12761302
// Recursively resolve the associated types to their concrete types.
12771303
RequirementSource nestedSource(RequirementSource::Redundant, Source.getLoc());
12781304
for (auto nested : T->getNestedTypes()) {

test/Generics/same_type_constraints.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,18 @@ struct EventHorizon : Timewarp {
318318
func activate<T>(_ t: T) {}
319319

320320
activate(Teleporter<EventHorizon, Beam>())
321+
322+
// rdar://problem/29288428
323+
class C {}
324+
325+
protocol P9 {
326+
associatedtype A
327+
}
328+
329+
struct X7<T: P9> where T.A : C { }
330+
331+
extension X7 where T.A == Int { } // expected-error 2{{'T' requires that 'Int' inherit from 'C'}}
332+
333+
struct X8<T: C> { }
334+
335+
extension X8 where T == Int { } // expected-error 2{{'T' requires that 'Int' inherit from 'C'}}

0 commit comments

Comments
 (0)