@@ -1089,20 +1089,20 @@ namespace {
1089
1089
return outputTy;
1090
1090
}
1091
1091
1092
- Type openPackElement (Type packType, ConstraintLocator *locator) {
1092
+ Type openPackElement (Type packType, ConstraintLocator *locator,
1093
+ PackExpansionExpr *packElementEnvironment) {
1093
1094
// If 'each t' is written outside of a pack expansion expression, allow the
1094
1095
// type to bind to a hole. The invalid pack reference will be diagnosed when
1095
1096
// attempting to bind the type variable for the underlying pack reference to
1096
1097
// a pack type without TVO_CanBindToPack.
1097
- if (PackElementEnvironments. empty () ) {
1098
+ if (!packElementEnvironment ) {
1098
1099
return CS.createTypeVariable (locator,
1099
1100
TVO_CanBindToHole | TVO_CanBindToNoEscape);
1100
1101
}
1101
1102
1102
1103
// The type of a PackElementExpr is the opened pack element archetype
1103
1104
// of the pack reference.
1104
- OpenPackElementType openPackElement (CS, locator,
1105
- PackElementEnvironments.back ());
1105
+ OpenPackElementType openPackElement (CS, locator, packElementEnvironment);
1106
1106
return openPackElement (packType, /* packRepr*/ nullptr );
1107
1107
}
1108
1108
@@ -1124,6 +1124,26 @@ namespace {
1124
1124
1125
1125
void addPackElementEnvironment (PackExpansionExpr *expr) {
1126
1126
PackElementEnvironments.push_back (expr);
1127
+
1128
+ SmallVector<ASTNode, 2 > expandedPacks;
1129
+ collectExpandedPacks (expr, expandedPacks);
1130
+ for (auto pack : expandedPacks) {
1131
+ if (auto *elementExpr = getAsExpr<PackElementExpr>(pack)) {
1132
+ CS.addPackEnvironment (elementExpr, expr);
1133
+ }
1134
+ }
1135
+
1136
+ auto *patternLoc = CS.getConstraintLocator (
1137
+ expr, ConstraintLocator::PackExpansionPattern);
1138
+ auto patternType = CS.createTypeVariable (
1139
+ patternLoc,
1140
+ TVO_CanBindToPack | TVO_CanBindToNoEscape | TVO_CanBindToHole);
1141
+ auto *shapeLoc =
1142
+ CS.getConstraintLocator (expr, ConstraintLocator::PackShape);
1143
+ auto *shapeTypeVar = CS.createTypeVariable (
1144
+ shapeLoc, TVO_CanBindToPack | TVO_CanBindToHole);
1145
+ auto expansionType = PackExpansionType::get (patternType, shapeTypeVar);
1146
+ CS.setType (expr, expansionType);
1127
1147
}
1128
1148
1129
1149
virtual Type visitErrorExpr (ErrorExpr *E) {
@@ -1384,6 +1404,17 @@ namespace {
1384
1404
return BoundGenericStructType::get (regexDecl, Type (), {matchType});
1385
1405
}
1386
1406
1407
+ PackExpansionExpr *getParentPackExpansionExpr (Expr *E) const {
1408
+ auto *current = E;
1409
+ while (auto *parent = CS.getParentExpr (current)) {
1410
+ if (auto *expansion = dyn_cast<PackExpansionExpr>(parent)) {
1411
+ return expansion;
1412
+ }
1413
+ current = parent;
1414
+ }
1415
+ return nullptr ;
1416
+ }
1417
+
1387
1418
Type visitDeclRefExpr (DeclRefExpr *E) {
1388
1419
auto locator = CS.getConstraintLocator (E);
1389
1420
@@ -1426,13 +1457,15 @@ namespace {
1426
1457
1427
1458
// value packs cannot be referenced without `each` immediately
1428
1459
// preceding them.
1429
- if (auto *expansion = knownType->getAs <PackExpansionType>()) {
1430
- if (!PackElementEnvironments.empty () &&
1460
+ if (auto *expansionType = knownType->getAs <PackExpansionType>()) {
1461
+ if (auto *parentExpansionExpr = getParentPackExpansionExpr (E);
1462
+ parentExpansionExpr &&
1431
1463
!isExpr<PackElementExpr>(CS.getParentExpr (E))) {
1432
- auto packType = expansion ->getPatternType ();
1464
+ auto packType = expansionType ->getPatternType ();
1433
1465
(void )CS.recordFix (
1434
1466
IgnoreMissingEachKeyword::create (CS, packType, locator));
1435
- auto eltType = openPackElement (packType, locator);
1467
+ auto eltType =
1468
+ openPackElement (packType, locator, parentExpansionExpr);
1436
1469
CS.setType (E, eltType);
1437
1470
return eltType;
1438
1471
}
@@ -3033,21 +3066,11 @@ namespace {
3033
3066
assert (PackElementEnvironments.back () == expr);
3034
3067
PackElementEnvironments.pop_back ();
3035
3068
3036
- auto *patternLoc =
3037
- CS.getConstraintLocator (expr, ConstraintLocator::PackExpansionPattern);
3038
- auto patternTy = CS.createTypeVariable (patternLoc,
3039
- TVO_CanBindToPack |
3040
- TVO_CanBindToNoEscape |
3041
- TVO_CanBindToHole);
3069
+ auto expansionType = CS.getType (expr)->castTo <PackExpansionType>();
3042
3070
auto elementResultType = CS.getType (expr->getPatternExpr ());
3043
3071
CS.addConstraint (ConstraintKind::PackElementOf, elementResultType,
3044
- patternTy, CS.getConstraintLocator (expr));
3045
-
3046
- auto *shapeLoc =
3047
- CS.getConstraintLocator (expr, ConstraintLocator::PackShape);
3048
- auto *shapeTypeVar = CS.createTypeVariable (shapeLoc,
3049
- TVO_CanBindToPack |
3050
- TVO_CanBindToHole);
3072
+ expansionType->getPatternType (),
3073
+ CS.getConstraintLocator (expr));
3051
3074
3052
3075
// Generate ShapeOf constraints between all packs expanded by this
3053
3076
// pack expansion expression through the shape type variable.
@@ -3061,9 +3084,14 @@ namespace {
3061
3084
3062
3085
for (auto pack : expandedPacks) {
3063
3086
Type packType;
3064
- if (auto *elementExpr = getAsExpr<PackElementExpr>(pack)) {
3065
- packType = CS.getType (elementExpr->getPackRefExpr ());
3066
- } else if (auto *elementType = getAsTypeRepr<PackElementTypeRepr>(pack)) {
3087
+ // / Skipping over pack elements because the relationship to its
3088
+ // / environment is now established during \c addPackElementEnvironment
3089
+ // / upon visiting its pack expansion and the Shape constraint added
3090
+ // / upon visiting the pack element.
3091
+ if (isExpr<PackElementExpr>(pack)) {
3092
+ continue ;
3093
+ } else if (auto *elementType =
3094
+ getAsTypeRepr<PackElementTypeRepr>(pack)) {
3067
3095
// OpenPackElementType sets types for 'each T' type reprs in
3068
3096
// expressions. Some invalid code won't make it there, and
3069
3097
// the constraint system won't have recorded a type.
@@ -3076,11 +3104,11 @@ namespace {
3076
3104
}
3077
3105
3078
3106
CS.addConstraint (
3079
- ConstraintKind::ShapeOf, shapeTypeVar , packType,
3107
+ ConstraintKind::ShapeOf, expansionType-> getCountType () , packType,
3080
3108
CS.getConstraintLocator (expr, ConstraintLocator::PackShape));
3081
3109
}
3082
3110
3083
- return PackExpansionType::get (patternTy, shapeTypeVar) ;
3111
+ return expansionType ;
3084
3112
}
3085
3113
3086
3114
Type visitPackElementExpr (PackElementExpr *expr) {
@@ -3094,7 +3122,18 @@ namespace {
3094
3122
CS.setType (expr->getPackRefExpr (), packType);
3095
3123
}
3096
3124
3097
- return openPackElement (packType, CS.getConstraintLocator (expr));
3125
+ auto *packEnvironment = CS.getPackEnvironment (expr);
3126
+ if (packEnvironment) {
3127
+ auto expansionType =
3128
+ CS.getType (packEnvironment)->castTo <PackExpansionType>();
3129
+ CS.addConstraint (ConstraintKind::ShapeOf, expansionType->getCountType (),
3130
+ packType,
3131
+ CS.getConstraintLocator (packEnvironment,
3132
+ ConstraintLocator::PackShape));
3133
+ }
3134
+
3135
+ return openPackElement (packType, CS.getConstraintLocator (expr),
3136
+ packEnvironment);
3098
3137
}
3099
3138
3100
3139
Type visitMaterializePackExpr (MaterializePackExpr *expr) {
0 commit comments