Skip to content

Commit a9df3e2

Browse files
authored
Merge pull request #67034 from artemcm/SimplifyConstExtractOpaqueTypes
[Compile Time Constant Extraction] Refactor collection of opaque type requirements to rely on pre-built Generic Signatures
2 parents 139672f + 72ed4e3 commit a9df3e2

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)