Skip to content

Commit e4ff3a5

Browse files
committed
[Mangling] Mangle generic signature requirements not satisfied by parent context.
The mangler had some ad hoc logic for only mangling requirements in a generic signature that are not requirements in the parent context's generic signature. However, it was based on an heuristic that isn't correct. Replace that logic with a check to determine whether the requirement is satisfied by the parent generic signature, which is far simpler. Fixes rdar://problem/31889040 / SR-6107.
1 parent 2adfb5a commit e4ff3a5

File tree

3 files changed

+26
-36
lines changed

3 files changed

+26
-36
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,17 +1736,6 @@ static bool isMethodDecl(const Decl *decl) {
17361736
&& decl->getDeclContext()->isTypeContext();
17371737
}
17381738

1739-
static bool genericParamIsBelowDepth(Type type, unsigned methodDepth) {
1740-
if (!type->hasTypeParameter())
1741-
return true;
1742-
1743-
return !type.findIf([methodDepth](Type t) -> bool {
1744-
if (auto *gp = t->getAs<GenericTypeParamType>())
1745-
return gp->getDepth() >= methodDepth;
1746-
return false;
1747-
});
1748-
}
1749-
17501739
CanType ASTMangler::getDeclTypeForMangling(
17511740
const ValueDecl *decl,
17521741
ArrayRef<GenericTypeParamType *> &genericParams,
@@ -1803,25 +1792,12 @@ CanType ASTMangler::getDeclTypeForMangling(
18031792

18041793
requirementsBuf.clear();
18051794
for (auto &reqt : sig->getRequirements()) {
1806-
switch (reqt.getKind()) {
1807-
case RequirementKind::Conformance:
1808-
case RequirementKind::Layout:
1809-
case RequirementKind::Superclass:
1810-
// We don't need the requirement if the constrained type is below the
1811-
// method depth.
1812-
if (genericParamIsBelowDepth(reqt.getFirstType(), initialParamDepth))
1813-
continue;
1814-
break;
1815-
case RequirementKind::SameType:
1816-
// We don't need the requirement if both types are below the method
1817-
// depth, or non-dependent.
1818-
if (genericParamIsBelowDepth(reqt.getFirstType(), initialParamDepth) &&
1819-
genericParamIsBelowDepth(reqt.getSecondType(), initialParamDepth))
1795+
// If the requirement is satisfied by the enclosing context,
1796+
// we don't need to mangle it here.
1797+
if (parentGenericSig->isRequirementSatisfied(reqt))
18201798
continue;
1821-
break;
1822-
}
18231799

1824-
// If we fell through the switch, mangle the requirement.
1800+
// Mangle the requirement.
18251801
requirementsBuf.push_back(reqt);
18261802
}
18271803
requirements = requirementsBuf;

lib/AST/GenericSignature.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -678,14 +678,17 @@ bool GenericSignature::isRequirementSatisfied(Requirement requirement) {
678678
case RequirementKind::Layout: {
679679
auto requiredLayout = requirement.getLayoutConstraint();
680680

681-
if (canFirstType->isTypeParameter())
682-
return getLayoutConstraint(canFirstType) == requiredLayout;
683-
else {
684-
// The requirement is on a concrete type, so it's either globally correct
685-
// or globally incorrect, independent of this generic context. The latter
686-
// case should be diagnosed elsewhere, so let's assume it's correct.
687-
return true;
681+
if (canFirstType->isTypeParameter()) {
682+
if (auto layout = getLayoutConstraint(canFirstType))
683+
return static_cast<bool>(layout.merge(requiredLayout));
684+
685+
return false;
688686
}
687+
688+
// The requirement is on a concrete type, so it's either globally correct
689+
// or globally incorrect, independent of this generic context. The latter
690+
// case should be diagnosed elsewhere, so let's assume it's correct.
691+
return true;
689692
}
690693
}
691694
}

test/SILGen/mangling_generic_extensions.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extension Foo {
2121
// NO-SELF-LABEL: sil hidden @_T027mangling_generic_extensions3FooV4zangyqd__lF
2222
func zang<U>(_: U) { }
2323
// NO-SELF-LABEL: sil hidden @_T027mangling_generic_extensions3FooV4zungyqd__AA8RuncibleRd__3HatQyd__Rs_lF
24-
func zung<U: Runcible where U.Hat == T>(_: U) { }
24+
func zung<U: Runcible>(_: U) where U.Hat == T { }
2525
}
2626

2727
extension Foo where T: Runcible {
@@ -56,3 +56,14 @@ extension Runcible where Self.Spoon == Self.Hat {
5656
// CHECK-LABEL: sil hidden @_T027mangling_generic_extensions8RunciblePA2aBRz5SpoonQz3HatRtzlE5runceyyF
5757
func runce() {}
5858
}
59+
60+
61+
struct Bar<T: Runcible, U: Runcible> { }
62+
63+
extension Bar {
64+
// CHECK-LABEL: _T027mangling_generic_extensions3BarV4bar1yqd__AA8RuncibleRd__AaE5SpoonRpzAFQy_AGRSlF
65+
func bar1<V: Runcible>(_: V) where U.Spoon: Runcible, T.Spoon == U.Spoon { }
66+
67+
// CHECK-LABEL: _T027mangling_generic_extensions3BarV4bar1yqd__AA8RuncibleRd__AaE5SpoonRp_lF
68+
func bar1<V: Runcible>(_: V) where U.Spoon: Runcible { }
69+
}

0 commit comments

Comments
 (0)