Skip to content

Commit 27aa365

Browse files
committed
[ConstraintSystem] Open pack element types using a PackElementOf constraint
when resolving pack reference type reprs inside pack expansion expressions.
1 parent 454913a commit 27aa365

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6108,6 +6108,30 @@ class HandlePlaceholderType {
61086108
}
61096109
};
61106110

6111+
/// A function object that opens a given pack type by generating a
6112+
/// \c PackElementOf constraint.
6113+
class OpenPackElementType {
6114+
ConstraintSystem &cs;
6115+
ConstraintLocator *locator;
6116+
GenericEnvironment *elementEnv;
6117+
6118+
public:
6119+
explicit OpenPackElementType(ConstraintSystem &cs,
6120+
ConstraintLocator *locator,
6121+
GenericEnvironment *elementEnv)
6122+
: cs(cs), locator(locator), elementEnv(elementEnv) {}
6123+
6124+
Type operator()(Type packType) const {
6125+
auto *elementType = cs.createTypeVariable(locator, TVO_CanBindToHole);
6126+
auto elementLoc = cs.getConstraintLocator(locator,
6127+
LocatorPathElt::OpenedPackElement(elementEnv));
6128+
6129+
cs.addConstraint(ConstraintKind::PackElementOf, elementType,
6130+
packType, elementLoc);
6131+
return elementType;
6132+
}
6133+
};
6134+
61116135
/// Compute the shuffle required to map from a given tuple type to
61126136
/// another tuple type.
61136137
///

lib/Sema/CSGen.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,13 +1416,20 @@ namespace {
14161416
Type
14171417
resolveTypeReferenceInExpression(TypeRepr *repr, TypeResolverContext resCtx,
14181418
const ConstraintLocatorBuilder &locator) {
1419+
TypeResolutionOptions options(resCtx);
1420+
14191421
// Introduce type variables for unbound generics.
14201422
const auto genericOpener = OpenUnboundGenericType(CS, locator);
14211423
const auto placeholderHandler = HandlePlaceholderType(CS, locator);
1422-
// FIXME: Open pack elements with a PackElementOf constraint.
14231424
OpenPackElementFn packElementOpener = nullptr;
1425+
if (!PackElementEnvironments.empty()) {
1426+
options |= TypeResolutionFlags::AllowPackReferences;
1427+
packElementOpener = OpenPackElementType(CS,
1428+
CS.getConstraintLocator(locator), PackElementEnvironments.back());
1429+
}
1430+
14241431
const auto result = TypeResolution::resolveContextualType(
1425-
repr, CS.DC, resCtx, genericOpener, placeholderHandler,
1432+
repr, CS.DC, options, genericOpener, placeholderHandler,
14261433
packElementOpener);
14271434
if (result->hasError()) {
14281435
CS.recordFix(
@@ -1662,16 +1669,20 @@ namespace {
16621669
ArrayRef<TypeRepr *> specializationArgs) {
16631670
// Resolve each type.
16641671
SmallVector<Type, 2> specializationArgTypes;
1665-
const auto options =
1672+
auto options =
16661673
TypeResolutionOptions(TypeResolverContext::InExpression);
16671674
for (auto specializationArg : specializationArgs) {
1675+
OpenPackElementFn packElementOpener = nullptr;
1676+
if (!PackElementEnvironments.empty()) {
1677+
options |= TypeResolutionFlags::AllowPackReferences;
1678+
packElementOpener = OpenPackElementType(CS, locator, PackElementEnvironments.back());
1679+
}
16681680
const auto result = TypeResolution::resolveContextualType(
16691681
specializationArg, CurDC, options,
16701682
// Introduce type variables for unbound generics.
16711683
OpenUnboundGenericType(CS, locator),
16721684
HandlePlaceholderType(CS, locator),
1673-
// FIXME: Open pack elements with a PackElementOf constraint.
1674-
/*packElementOpener*/ nullptr);
1685+
packElementOpener);
16751686
if (result->hasError())
16761687
return true;
16771688

@@ -1728,16 +1739,21 @@ namespace {
17281739
// Bind the specified generic arguments to the type variables in the
17291740
// open type.
17301741
auto *const locator = CS.getConstraintLocator(expr);
1731-
const auto options =
1742+
auto options =
17321743
TypeResolutionOptions(TypeResolverContext::InExpression);
17331744
for (size_t i = 0, e = specializations.size(); i < e; ++i) {
1745+
OpenPackElementFn packElementOpener = nullptr;
1746+
if (!PackElementEnvironments.empty()) {
1747+
options |= TypeResolutionFlags::AllowPackReferences;
1748+
packElementOpener = OpenPackElementType(CS, locator, PackElementEnvironments.back());
1749+
}
1750+
17341751
const auto result = TypeResolution::resolveContextualType(
17351752
specializations[i], CS.DC, options,
17361753
// Introduce type variables for unbound generics.
17371754
OpenUnboundGenericType(CS, locator),
17381755
HandlePlaceholderType(CS, locator),
1739-
// FIXME: Open pack elements with a PackElementOf constraint.
1740-
/*packElementOpener*/ nullptr);
1756+
packElementOpener);
17411757
if (result->hasError())
17421758
return Type();
17431759

@@ -3001,18 +3017,12 @@ namespace {
30013017

30023018
Type visitPackElementExpr(PackElementExpr *expr) {
30033019
auto packType = CS.getType(expr->getPackRefExpr());
3004-
auto *elementType =
3005-
CS.createTypeVariable(CS.getConstraintLocator(expr),
3006-
TVO_CanBindToHole);
3007-
auto *elementEnv = PackElementEnvironments.back();
3008-
auto *elementLoc = CS.getConstraintLocator(
3009-
expr, LocatorPathElt::OpenedPackElement(elementEnv));
30103020

30113021
// The type of a PackElementExpr is the opened pack element archetype
30123022
// of the pack reference.
3013-
CS.addConstraint(ConstraintKind::PackElementOf, elementType, packType,
3014-
elementLoc);
3015-
return elementType;
3023+
OpenPackElementType openPackElement(CS, CS.getConstraintLocator(expr),
3024+
PackElementEnvironments.back());
3025+
return openPackElement(packType);
30163026
}
30173027

30183028
Type visitDynamicTypeExpr(DynamicTypeExpr *expr) {

0 commit comments

Comments
 (0)