Skip to content

Commit 72ed4e3

Browse files
committed
[Compile Time Constant Extraction] Refactor collection of opaque type requirements
To reduce duplication of logic with other parts of the compiler, instead of destructuring the constraint type, write the requirements in the opaque type declaration's generic signature.
1 parent 61e8585 commit 72ed4e3

File tree

3 files changed

+91
-71
lines changed

3 files changed

+91
-71
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 29 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -811,78 +811,41 @@ void writeAttrInformation(llvm::json::OStream &JSON,
811811
});
812812
}
813813

814-
void writeParameterizedProtocolSameTypeRequirements(
815-
llvm::json::OStream &JSON,
816-
const ParameterizedProtocolType &ParameterizedProtoTy) {
817-
auto Protocol = ParameterizedProtoTy.getProtocol();
818-
auto Requirements = Protocol->getProtocolRequirements();
819-
auto ParameterTypeNames = Protocol->getPrimaryAssociatedTypeNames();
820-
auto ProtocolArguments = ParameterizedProtoTy.getArgs();
821-
llvm::dbgs() << Requirements.size() << "\n";
822-
assert(ProtocolArguments.size() >= ParameterTypeNames.size());
823-
824-
for (size_t i = 0; i < ProtocolArguments.size(); ++i) {
825-
auto ProtocolArgumentTy = ProtocolArguments[i];
826-
std::string ArgumentName = ParameterTypeNames.size() > i
827-
? ParameterTypeNames[i].first.str().str()
828-
: "unknown";
829-
830-
JSON.object([&] {
831-
auto QualifiedTypeAliasName = toFullyQualifiedProtocolNameString(
832-
*ParameterizedProtoTy.getProtocol()) +
833-
"." + ArgumentName;
834-
JSON.attribute("typeAliasName", QualifiedTypeAliasName);
835-
JSON.attribute("substitutedTypeName",
836-
toFullyQualifiedTypeNameString(ProtocolArgumentTy));
837-
JSON.attribute("substitutedMangledTypeName",
838-
toMangledTypeNameString(ProtocolArgumentTy));
839-
});
840-
}
841-
}
842-
843-
void writeOpaqueTypeProtocolCompositionSameTypeRequirements(
844-
llvm::json::OStream &JSON,
845-
const ProtocolCompositionType &ProtocolCompositionTy) {
846-
for (auto CompositionMemberProto : ProtocolCompositionTy.getMembers()) {
847-
if (auto ParameterizedProtoTy =
848-
CompositionMemberProto->getAs<ParameterizedProtocolType>()) {
849-
writeParameterizedProtocolSameTypeRequirements(JSON,
850-
*ParameterizedProtoTy);
851-
}
852-
}
853-
}
854-
855814
void writeSubstitutedOpaqueTypeAliasDetails(
856815
llvm::json::OStream &JSON, const OpaqueTypeArchetypeType &OpaqueTy) {
816+
auto Signature = OpaqueTy.getDecl()->getOpaqueInterfaceGenericSignature();
817+
857818
JSON.attributeArray("opaqueTypeProtocolRequirements", [&] {
858-
auto ConformsToProtocols = OpaqueTy.getConformsTo();
859-
for (auto Proto : ConformsToProtocols) {
860-
JSON.value(toFullyQualifiedProtocolNameString(*Proto));
819+
for (const auto Requirement : Signature.getRequirements()) {
820+
// Ignore requirements whose subject type is that of the owner decl
821+
if (!Requirement.getFirstType()->isEqual(OpaqueTy.getInterfaceType()))
822+
continue;
823+
if (Requirement.getKind() == RequirementKind::Conformance)
824+
JSON.value(
825+
toFullyQualifiedProtocolNameString(*Requirement.getProtocolDecl()));
861826
}
862827
});
828+
863829
JSON.attributeArray("opaqueTypeSameTypeRequirements", [&] {
864-
auto GenericSig = OpaqueTy.getDecl()
865-
->getNamingDecl()
866-
->getInnermostDeclContext()
867-
->getGenericSignatureOfContext();
868-
auto ConstraintTy = OpaqueTy.getExistentialType();
869-
if (auto existential = ConstraintTy->getAs<ExistentialType>())
870-
ConstraintTy = existential->getConstraintType();
871-
872-
// Opaque archetype substitutions are always canonical, so
873-
// re-sugar the constraint type using the owning
874-
// declaration's generic parameter names.
875-
if (GenericSig)
876-
ConstraintTy = GenericSig->getSugaredType(ConstraintTy);
877-
878-
if (auto ParameterizedProtoTy =
879-
ConstraintTy->getAs<ParameterizedProtocolType>()) {
880-
writeParameterizedProtocolSameTypeRequirements(JSON,
881-
*ParameterizedProtoTy);
882-
} else if (auto ProtocolCompositionTy =
883-
ConstraintTy->getAs<ProtocolCompositionType>()) {
884-
writeOpaqueTypeProtocolCompositionSameTypeRequirements(
885-
JSON, *ProtocolCompositionTy);
830+
for (const auto Requirement : Signature.getRequirements()) {
831+
if (Requirement.getKind() == RequirementKind::SameType) {
832+
auto TypeAliasType = Requirement.getFirstType();
833+
auto TypeWitness = Requirement.getSecondType();
834+
JSON.object([&] {
835+
auto TypeAliasName = toFullyQualifiedTypeNameString(TypeAliasType);
836+
if (auto DependentMemberTy =
837+
TypeAliasType->getAs<DependentMemberType>())
838+
if (const auto *Assoc = DependentMemberTy->getAssocType())
839+
TypeAliasName =
840+
toFullyQualifiedProtocolNameString(*Assoc->getProtocol()) +
841+
"." + DependentMemberTy->getName().str().str();
842+
JSON.attribute("typeAliasName", TypeAliasName);
843+
JSON.attribute("substitutedTypeName",
844+
toFullyQualifiedTypeNameString(TypeWitness));
845+
JSON.attribute("substitutedMangledTypeName",
846+
toMangledTypeNameString(TypeWitness));
847+
});
848+
}
886849
}
887850
});
888851
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// REQUIRES: OS=macosx
2+
// RUN: %empty-directory(%t)
3+
// RUN: %empty-directory(%t/includes)
4+
// RUN: echo "[myProto]" > %t/protocols.json
5+
6+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.15 -typecheck -emit-const-values-path %t/ExtractOpaqueGenericTypealias.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s -I %t/includes
7+
// RUN: cat %t/ExtractOpaqueGenericTypealias.swiftconstvalues 2>&1 | %FileCheck %s
8+
9+
protocol myProto {
10+
associatedtype T
11+
func foo() -> T
12+
}
13+
14+
protocol protoA<T> {
15+
associatedtype T
16+
}
17+
18+
struct A<K> : protoA {
19+
typealias T = K
20+
}
21+
22+
struct Foo<L : Hashable> : myProto {
23+
func foo() -> some protoA<Int> { return A() }
24+
func bar(_ param : L) {}
25+
}
26+
27+
// CHECK: [
28+
// CHECK-NEXT: {
29+
// CHECK-NEXT: "typeName": "ExtractOpaqueGenericTypealias.Foo<L>",
30+
// CHECK-NEXT: "mangledTypeName": "29ExtractOpaqueGenericTypealias3FooVyxG",
31+
// CHECK-NEXT: "kind": "generic struct",
32+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractOpaqueGenericTypealias.swift",
33+
// CHECK-NEXT: "line": 22,
34+
// CHECK-NEXT: "conformances": [
35+
// CHECK-NEXT: "ExtractOpaqueGenericTypealias.myProto",
36+
// CHECK-NEXT: "Swift.Sendable"
37+
// CHECK-NEXT: ],
38+
// CHECK-NEXT: "associatedTypeAliases": [
39+
// CHECK-NEXT: {
40+
// CHECK-NEXT: "typeAliasName": "T",
41+
// CHECK-NEXT: "substitutedTypeName": "some ExtractOpaqueGenericTypealias.protoA<Swift.Int>",
42+
// CHECK-NEXT: "substitutedMangledTypeName": "29ExtractOpaqueGenericTypealias3FooV3fooQryFQOyx_Qo_",
43+
// CHECK-NEXT: "opaqueTypeProtocolRequirements": [
44+
// CHECK-NEXT: "ExtractOpaqueGenericTypealias.protoA"
45+
// CHECK-NEXT: ],
46+
// CHECK-NEXT: "opaqueTypeSameTypeRequirements": [
47+
// CHECK-NEXT: {
48+
// CHECK-NEXT: "typeAliasName": "ExtractOpaqueGenericTypealias.protoA.T",
49+
// CHECK-NEXT: "substitutedTypeName": "Swift.Int",
50+
// CHECK-NEXT: "substitutedMangledTypeName": "Si"
51+
// CHECK-NEXT: }
52+
// CHECK-NEXT: ]
53+
// CHECK-NEXT: }
54+
// CHECK-NEXT: ],
55+
// CHECK-NEXT: "properties": []
56+
// CHECK-NEXT: }
57+
// CHECK-NEXT: ]

test/ConstExtraction/ExtractOpaqueTypealias.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ private func baz() -> some protoA<testModBStruct> & protoB<Float> & testModBProt
5656
// CHECK-NEXT: ],
5757
// CHECK-NEXT: "opaqueTypeSameTypeRequirements": [
5858
// CHECK-NEXT: {
59-
// CHECK-NEXT: "typeAliasName": "ExtractOpaqueTypealias.protoA.T",
60-
// CHECK-NEXT: "substitutedTypeName": "testModB.testModBStruct",
61-
// CHECK-NEXT: "substitutedMangledTypeName": "8testModB0aB7BStructV"
62-
// CHECK-NEXT: },
63-
// CHECK-NEXT: {
6459
// CHECK-NEXT: "typeAliasName": "ExtractOpaqueTypealias.protoB.K",
6560
// CHECK-NEXT: "substitutedTypeName": "Swift.Float",
6661
// CHECK-NEXT: "substitutedMangledTypeName": "Sf"
6762
// CHECK-NEXT: }
63+
// CHECK-NEXT: {
64+
// CHECK-NEXT: "typeAliasName": "ExtractOpaqueTypealias.protoA.T",
65+
// CHECK-NEXT: "substitutedTypeName": "testModB.testModBStruct",
66+
// CHECK-NEXT: "substitutedMangledTypeName": "8testModB0aB7BStructV"
67+
// CHECK-NEXT: }
6868
// CHECK-NEXT: ]
6969
// CHECK-NEXT: }
7070
// CHECK-NEXT: ],

0 commit comments

Comments
 (0)