ModuleInterface: Resolve inherited types when recording indirect conformances.

Previously, indirect public conformances provided by conforming to an internal
protocol could be skipped in a `.swiftinterface` in lazy typechecking mode
since inherited types might not be resolved before collecting the indirect
conformances.
This commit is contained in:
Allan Shortlidge
2023-09-06 16:59:10 -07:00
parent 435f623caf
commit eee122c093
5 changed files with 28 additions and 2 deletions

View File

@@ -483,8 +483,8 @@ class InheritedProtocolCollector {
bool skipExtra = false) {
llvm::Optional<AvailableAttrList> availableAttrs;
for (InheritedEntry inherited : directlyInherited.getEntries()) {
Type inheritedTy = inherited.getType();
for (int i : directlyInherited.getIndices()) {
Type inheritedTy = directlyInherited.getResolvedType(i);
if (!inheritedTy || !inheritedTy->isExistentialType())
continue;
@@ -492,6 +492,7 @@ class InheritedProtocolCollector {
if (!canPrintNormally && skipExtra)
continue;
auto inherited = directlyInherited.getEntry(i);
ExistentialLayout layout = inheritedTy->getExistentialLayout();
for (ProtocolDecl *protoDecl : layout.getProtocols()) {
if (canPrintNormally)

View File

@@ -62,6 +62,10 @@ protocol InternalProto {
func badReq() -> DoesNotExist // expected-error {{cannot find type 'DoesNotExist' in scope}}
}
protocol InternalProtoConformingToPublicProto: PublicProto {
func internalReq() -> DoesNotExist // expected-error {{cannot find type 'DoesNotExist' in scope}}
}
public struct PublicStruct {
// FIXME: Test properties
@@ -130,6 +134,13 @@ public struct PublicStructConformingToPublicProto: PublicProto {
}
}
public struct PublicStructIndirectlyConformingToPublicProto: InternalProtoConformingToPublicProto {
public init() {}
public func req() -> Int {
return true // expected-error {{cannot convert return expression of type 'Bool' to return type 'Int'}}
}
}
public class PublicClassConformingToPublicProto: PublicProto {
public init() {}
public func req() -> Int {

View File

@@ -39,6 +39,7 @@ func testPublicClass() {
func testConformances() {
let array: [any PublicProto] = [
PublicStructConformingToPublicProto(),
PublicStructIndirectlyConformingToPublicProto(),
PublicClassConformingToPublicProto(),
"string",
PublicClassInheritingConformanceToPublicProto(),
@@ -46,5 +47,6 @@ func testConformances() {
for x in array {
_ = x.req()
constrainedGenericPublicFunction(x)
}
}

View File

@@ -53,6 +53,10 @@
// CHECK: public init()
// CHECK: public func req() -> Swift.Int
// CHECK: }
// CHECK: public struct PublicStructIndirectlyConformingToPublicProto {
// CHECK: public init()
// CHECK: public func req() -> Swift.Int
// CHECK: }
// CHECK: public class PublicClassConformingToPublicProto : lazy_typecheck.PublicProto {
// CHECK: public init()
// CHECK: public func req() -> Swift.Int
@@ -70,3 +74,4 @@
// CHECK: public func req() throws -> Swift.Int
// CHECK: }
// CHECK: #endif
// CHECK: extension lazy_typecheck.PublicStructIndirectlyConformingToPublicProto : lazy_typecheck.PublicProto {}

View File

@@ -49,6 +49,13 @@ exports:
'_$s14lazy_typecheck034PublicClassInheritingConformanceToC5ProtoCN',
'_$s14lazy_typecheck034PublicClassInheritingConformanceToC5ProtoCfD',
'_$s14lazy_typecheck034PublicClassInheritingConformanceToC5ProtoCfd',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoV3reqSiyF',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVAA0cH0AAMc',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVAA0cH0AAWP',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVACycfC',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVMa',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVMn',
'_$s14lazy_typecheck034PublicStructIndirectlyConformingToC5ProtoVN',
'_$s14lazy_typecheck10publicFuncSiyF', '_$s14lazy_typecheck11PublicClassC06publicD6MethodyyFZTj',
'_$s14lazy_typecheck11PublicClassC06publicD6MethodyyFZTq',
'_$s14lazy_typecheck11PublicClassC12publicMethodSiyFTj', '_$s14lazy_typecheck11PublicClassC12publicMethodSiyFTq',