Skip to content

Commit 1b798d0

Browse files
committed
ASTMangler: Consolidate duplicated code for conditional requirements
1 parent 50794ee commit 1b798d0

File tree

2 files changed

+51
-50
lines changed

2 files changed

+51
-50
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,31 @@ static bool isRetroactiveConformance(const RootProtocolConformance *root) {
18721872
return conformance->isRetroactive();
18731873
}
18741874

1875+
template<typename Fn>
1876+
static bool forEachConditionalConformance(const ProtocolConformance *conformance,
1877+
Fn fn) {
1878+
auto *rootConformance = conformance->getRootConformance();
1879+
1880+
auto subMap = conformance->getSubstitutionMap();
1881+
for (auto requirement : rootConformance->getConditionalRequirements()) {
1882+
if (requirement.getKind() != RequirementKind::Conformance)
1883+
continue;
1884+
ProtocolDecl *proto = requirement.getProtocolDecl();
1885+
auto conformance = subMap.lookupConformance(
1886+
requirement.getFirstType()->getCanonicalType(), proto);
1887+
if (conformance.isInvalid()) {
1888+
// This should only happen when mangling invalid ASTs, but that happens
1889+
// for indexing purposes.
1890+
continue;
1891+
}
1892+
1893+
if (fn(requirement.getFirstType().subst(subMap), conformance))
1894+
return true;
1895+
}
1896+
1897+
return false;
1898+
}
1899+
18751900
/// Determine whether the given protocol conformance contains a retroactive
18761901
/// protocol conformance anywhere in it.
18771902
static bool containsRetroactiveConformance(
@@ -1899,24 +1924,10 @@ static bool containsRetroactiveConformance(
18991924

19001925
// If the conformance is conditional and any of the substitutions used to
19011926
// satisfy the conditions are retroactive, it's retroactive.
1902-
auto subMap = conformance->getSubstitutionMap();
1903-
for (auto requirement : rootConformance->getConditionalRequirements()) {
1904-
if (requirement.getKind() != RequirementKind::Conformance)
1905-
continue;
1906-
ProtocolDecl *proto = requirement.getProtocolDecl();
1907-
auto conformance = subMap.lookupConformance(
1908-
requirement.getFirstType()->getCanonicalType(), proto);
1909-
if (conformance.isInvalid()) {
1910-
// This should only happen when mangling invalid ASTs, but that happens
1911-
// for indexing purposes.
1912-
continue;
1913-
}
1914-
if (containsRetroactiveConformance(conformance)) {
1915-
return true;
1916-
}
1917-
}
1918-
1919-
return false;
1927+
return forEachConditionalConformance(conformance,
1928+
[&](Type substType, ProtocolConformanceRef substConf) -> bool {
1929+
return containsRetroactiveConformance(substConf);
1930+
});
19201931
}
19211932

19221933
void ASTMangler::appendRetroactiveConformances(SubstitutionMap subMap,
@@ -4169,48 +4180,27 @@ void ASTMangler::appendAnyProtocolConformance(
41694180
void ASTMangler::appendConcreteProtocolConformance(
41704181
const ProtocolConformance *conformance,
41714182
GenericSignature sig) {
4172-
auto module = conformance->getDeclContext()->getParentModule();
4173-
41744183
// Conforming type.
41754184
Type conformingType = conformance->getType();
41764185
if (conformingType->hasArchetype())
41774186
conformingType = conformingType->mapTypeOutOfContext();
4178-
appendType(conformingType->getCanonicalType(), sig);
4187+
appendType(conformingType->getReducedType(sig), sig);
41794188

41804189
// Protocol conformance reference.
41814190
appendProtocolConformanceRef(conformance->getRootConformance());
41824191

41834192
// Conditional conformance requirements.
41844193
bool firstRequirement = true;
4185-
for (const auto &conditionalReq : conformance->getConditionalRequirements()) {
4186-
switch (conditionalReq.getKind()) {
4187-
case RequirementKind::SameShape:
4188-
llvm_unreachable("Same-shape requirement not supported here");
4189-
case RequirementKind::Layout:
4190-
case RequirementKind::SameType:
4191-
case RequirementKind::Superclass:
4192-
continue;
4193-
4194-
case RequirementKind::Conformance: {
4195-
auto type = conditionalReq.getFirstType();
4196-
if (type->hasArchetype())
4197-
type = type->mapTypeOutOfContext();
4198-
CanType canType = type->getReducedType(sig);
4199-
auto proto = conditionalReq.getProtocolDecl();
4200-
4201-
ProtocolConformanceRef conformance;
4202-
4203-
if (canType->isTypeParameter() || canType->is<OpaqueTypeArchetypeType>()){
4204-
conformance = ProtocolConformanceRef(proto);
4205-
} else {
4206-
conformance = module->lookupConformance(canType, proto);
4207-
}
4208-
appendAnyProtocolConformance(sig, canType, conformance);
4194+
forEachConditionalConformance(conformance,
4195+
[&](Type substType, ProtocolConformanceRef substConf) -> bool {
4196+
if (substType->hasArchetype())
4197+
substType = substType->mapTypeOutOfContext();
4198+
CanType canType = substType->getReducedType(sig);
4199+
appendAnyProtocolConformance(sig, canType, substConf);
42094200
appendListSeparator(firstRequirement);
4210-
break;
4211-
}
4212-
}
4213-
}
4201+
return false;
4202+
});
4203+
42144204
if (firstRequirement)
42154205
appendOperator("y");
42164206

test/IRGen/variadic_generic_opaque.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,15 @@ func variadicG2<each T: Q>(_: repeat each T) -> some P {
3939

4040
// CHECK: define private ptr @"get_witness_table 23variadic_generic_opaque2G2VyAA2S1V_AA2S2VQPGAA1PHPAeA1QHPyHC_AgaJHPyHCHX_HC"
4141
// CHECK: define private ptr @"get_witness_table 23variadic_generic_opaque1QRzlAA2G2VyAA2S1V_xQPGAA1PHPAfaBHPyHC_xAaBHD1_HX_HC"
42-
// CHECK: define private ptr @"get_witness_table Rvz23variadic_generic_opaque1QRzlAA2G2VyxxQp_QPGAA1PHPxAaBHD1__HX_HC"
42+
// CHECK: define private ptr @"get_witness_table Rvz23variadic_generic_opaque1QRzlAA2G2VyxxQp_QPGAA1PHPxAaBHD1__HX_HC"
43+
44+
// Conditional same-shape requirement
45+
public struct Outer<each T> {
46+
public struct Inner<each U> {}
47+
}
48+
49+
extension Outer.Inner: P where (repeat (each T, each U)): Any {}
50+
51+
func concreteOuterInner() -> some P {
52+
Outer<Int>.Inner<String>()
53+
}

0 commit comments

Comments
 (0)