Skip to content

Commit 2686ce3

Browse files
committed
AST: Hack around edge case due to broken abstract conformance representation
A substitution map might store an abstract conformance even if the replacement type is an archetype that conforms concretely via a superclass requirement. This is because when we build the substitution map, if the archetype is represented by a type parameter, we don't have enough information to know if it will conform abstractly or concretely.
1 parent 69bb2a7 commit 2686ce3

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

lib/AST/SubstitutionMap.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ SubstitutionMap::combineSubstitutionMaps(SubstitutionMap firstSubMap,
638638
// Some combination of storing substitution maps in BoundGenericTypes
639639
// as well as for method overrides would solve this, but for now, just
640640
// punt to module lookup.
641+
if (substType->isTypeParameter())
642+
return ProtocolConformanceRef(proto);
643+
641644
return proto->getParentModule()->lookupConformance(substType, proto);
642645
});
643646
}

lib/AST/Type.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4428,10 +4428,12 @@ operator()(CanType dependentType, Type conformingReplacementType,
44284428
ProtocolConformanceRef LookUpConformanceInSubstitutionMap::
44294429
operator()(CanType dependentType, Type conformingReplacementType,
44304430
ProtocolDecl *conformedProtocol) const {
4431-
// Lookup conformances for opened existential.
4432-
if (conformingReplacementType->isOpenedExistential()) {
4431+
// Lookup conformances for archetypes that conform concretely
4432+
// via a superclass.
4433+
if (auto archetypeType = conformingReplacementType->getAs<ArchetypeType>()) {
44334434
return conformedProtocol->getModuleContext()->lookupConformance(
4434-
conformingReplacementType, conformedProtocol);
4435+
conformingReplacementType, conformedProtocol,
4436+
/*allowMissing=*/true);
44354437
}
44364438
return Subs.lookupConformance(dependentType, conformedProtocol);
44374439
}

test/SILGen/vtable_generic_signature.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
protocol P {}
55
protocol Q : P {}
6+
class C : P {}
67

78
class ConcreteBase {
89
func f<U : Q>(_: U) {}
10+
func g<U : C>(_: U) {}
911
}
1012

1113
class ConcreteDerivedFromConcreteBase : ConcreteBase {
@@ -37,6 +39,10 @@ func call<T, U : P>(_ t: T, _ u: U) {
3739
GenericDerivedFromGenericBase<T>().f(u)
3840
}
3941

42+
class ConcreteDerived: ConcreteBase {
43+
override func g<U : P>(_: U) {}
44+
}
45+
4046
// All the vtable thunks should traffic in <U where U : Q>, because that's
4147
// what the base method declares.
4248

@@ -47,19 +53,22 @@ func call<T, U : P>(_ t: T, _ u: U) {
4753

4854
// CHECK-LABEL: sil_vtable ConcreteBase {
4955
// CHECK-NEXT: #ConcreteBase.f: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1fyyxAA1QRzlF
56+
// CHECK-NEXT: #ConcreteBase.g: <U where U : C> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1gyyxAA1CCRbzlF
5057
// CHECK-NEXT: #ConcreteBase.init!allocator: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature12ConcreteBaseCACycfC
5158
// CHECK-NEXT: #ConcreteBase.deinit!deallocator: @$s24vtable_generic_signature12ConcreteBaseCfD
5259
// CHECK-NEXT: }
5360

5461
// CHECK-LABEL: sil_vtable ConcreteDerivedFromConcreteBase {
5562
// CHECK-NEXT: #ConcreteBase.f: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlFAA0dG0CADyyxAA1QRzlFTV [override]
63+
// CHECK-NEXT: #ConcreteBase.g: <U where U : C> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1gyyxAA1CCRbzlF
5664
// CHECK-NEXT: #ConcreteBase.init!allocator: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseCACycfC [override]
5765
// CHECK-NEXT: #ConcreteDerivedFromConcreteBase.f: <U where U : P> (ConcreteDerivedFromConcreteBase) -> (U) -> () : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlF
5866
// CHECK-NEXT: #ConcreteDerivedFromConcreteBase.deinit!deallocator: @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseCfD
5967
// CHECK-NEXT: }
6068

6169
// CHECK-LABEL: sil_vtable GenericDerivedFromConcreteBase {
6270
// CHECK-NEXT: #ConcreteBase.f: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lFAA0gH0CADyyxAA1QRzlFTV [override]
71+
// CHECK-NEXT: #ConcreteBase.g: <U where U : C> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1gyyxAA1CCRbzlF
6372
// CHECK-NEXT: #ConcreteBase.init!allocator: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseCACyxGycfC [override]
6473
// CHECK-NEXT: #GenericDerivedFromConcreteBase.f: <T><U where U : P> (GenericDerivedFromConcreteBase<T>) -> (U) -> () : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lF
6574
// CHECK-NEXT: #GenericDerivedFromConcreteBase.deinit!deallocator: @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseCfD
@@ -84,3 +93,11 @@ func call<T, U : P>(_ t: T, _ u: U) {
8493
// CHECK-NEXT: #GenericDerivedFromGenericBase.f: <T><U where U : P> (GenericDerivedFromGenericBase<T>) -> (U) -> () : @$s24vtable_generic_signature018GenericDerivedFromD4BaseC1fyyqd__AA1PRd__lF
8594
// CHECK-NEXT: #GenericDerivedFromGenericBase.deinit!deallocator: @$s24vtable_generic_signature018GenericDerivedFromD4BaseCfD
8695
// CHECK-NEXT: }
96+
97+
// CHECK-LABEL: sil_vtable ConcreteDerived {
98+
// CHECK-NEXT: #ConcreteBase.f: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1fyyxAA1QRzlF [inherited]
99+
// CHECK-NEXT: #ConcreteBase.g: <U where U : C> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature15ConcreteDerivedC1gyyxAA1PRzlFAA0D4BaseCADyyxAA1CCRbzlFTV [override]
100+
// CHECK-NEXT: #ConcreteBase.init!allocator: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature15ConcreteDerivedCACycfC [override]
101+
// CHECK-NEXT: #ConcreteDerived.g: <U where U : P> (ConcreteDerived) -> (U) -> () : @$s24vtable_generic_signature15ConcreteDerivedC1gyyxAA1PRzlF
102+
// CHECK-NEXT: #ConcreteDerived.deinit!deallocator: @$s24vtable_generic_signature15ConcreteDerivedCfD // ConcreteDerived.__deallocating_deinit
103+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)