Skip to content

Commit 15db826

Browse files
committed
[Type substitution] Suppress redundant type parameters after substitution.
Substitution into a generic function type can map type parameters to other type parameters. In some cases, this was introducing duplicate type parameters, e.g., if two type parameters in the original signature mapped down to a single type parameter in the substituted signature. Sort/unique the resulting type parameters so we don't break invariants.
1 parent 921e14f commit 15db826

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

lib/AST/Type.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3561,6 +3561,36 @@ case TypeKind::Id:
35613561
return FunctionType::get(inputTy, resultTy, function->getExtInfo());
35623562
}
35633563

3564+
// Sort/unique the generic parameters by depth/index.
3565+
using llvm::array_pod_sort;
3566+
array_pod_sort(genericParams.begin(), genericParams.end(),
3567+
[](GenericTypeParamType * const * gpp1,
3568+
GenericTypeParamType * const * gpp2) {
3569+
auto gp1 = *gpp1;
3570+
auto gp2 = *gpp2;
3571+
3572+
if (gp1->getDepth() < gp2->getDepth())
3573+
return -1;
3574+
3575+
if (gp1->getDepth() > gp2->getDepth())
3576+
return 1;
3577+
3578+
if (gp1->getIndex() < gp2->getIndex())
3579+
return -1;
3580+
3581+
if (gp1->getIndex() > gp2->getIndex())
3582+
return 1;
3583+
3584+
return 0;
3585+
});
3586+
genericParams.erase(std::unique(genericParams.begin(), genericParams.end(),
3587+
[](GenericTypeParamType *gp1,
3588+
GenericTypeParamType *gp2) {
3589+
return gp1->getDepth() == gp2->getDepth()
3590+
&& gp1->getIndex() == gp2->getIndex();
3591+
}),
3592+
genericParams.end());
3593+
35643594
// Produce the new generic function type.
35653595
auto sig = GenericSignature::get(genericParams, requirements);
35663596
return GenericFunctionType::get(sig, inputTy, resultTy,

0 commit comments

Comments
 (0)