@@ -1089,6 +1089,23 @@ namespace {
10891089 return outputTy;
10901090 }
10911091
1092+ Type openPackElement (Type packType, ConstraintLocator *locator) {
1093+ // If 'each t' is written outside of a pack expansion expression, allow the
1094+ // type to bind to a hole. The invalid pack reference will be diagnosed when
1095+ // attempting to bind the type variable for the underlying pack reference to
1096+ // a pack type without TVO_CanBindToPack.
1097+ if (PackElementEnvironments.empty ()) {
1098+ return CS.createTypeVariable (locator,
1099+ TVO_CanBindToHole | TVO_CanBindToNoEscape);
1100+ }
1101+
1102+ // The type of a PackElementExpr is the opened pack element archetype
1103+ // of the pack reference.
1104+ OpenPackElementType openPackElement (CS, locator,
1105+ PackElementEnvironments.back ());
1106+ return openPackElement (packType, /* packRepr*/ nullptr );
1107+ }
1108+
10921109 public:
10931110 ConstraintGenerator (ConstraintSystem &CS, DeclContext *DC)
10941111 : CS(CS), CurDC(DC ? DC : CS.DC), CurrPhase(CS.getPhase()) {
@@ -1407,6 +1424,20 @@ namespace {
14071424 return invalidateReference ();
14081425 }
14091426
1427+ // value packs cannot be referenced without `each` immediately
1428+ // preceding them.
1429+ if (auto *expansion = knownType->getAs <PackExpansionType>()) {
1430+ if (!PackElementEnvironments.empty () &&
1431+ !isExpr<PackElementExpr>(CS.getParentExpr (E))) {
1432+ auto packType = expansion->getPatternType ();
1433+ (void )CS.recordFix (
1434+ IgnoreMissingEachKeyword::create (CS, packType, locator));
1435+ auto eltType = openPackElement (packType, locator);
1436+ CS.setType (E, eltType);
1437+ return eltType;
1438+ }
1439+ }
1440+
14101441 if (!knownType->hasPlaceholder ()) {
14111442 // Set the favored type for this expression to the known type.
14121443 CS.setFavoredType (E, knownType.getPointer ());
@@ -3063,6 +3094,67 @@ namespace {
30633094 return variadicSeq;
30643095 }
30653096
3097+ void collectExpandedPacks (PackExpansionExpr *expansion,
3098+ SmallVectorImpl<ASTNode> &packs) {
3099+ struct PackCollector : public ASTWalker {
3100+ private:
3101+ ConstraintSystem &CS;
3102+ SmallVectorImpl<ASTNode> &Packs;
3103+
3104+ public:
3105+ PackCollector (ConstraintSystem &cs, SmallVectorImpl<ASTNode> &packs)
3106+ : CS(cs), Packs(packs) {}
3107+
3108+ // / Walk everything that's available.
3109+ MacroWalking getMacroWalkingBehavior () const override {
3110+ return MacroWalking::ArgumentsAndExpansion;
3111+ }
3112+
3113+ virtual PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
3114+ // Don't walk into nested pack expansions
3115+ if (isa<PackExpansionExpr>(E)) {
3116+ return Action::SkipChildren (E);
3117+ }
3118+
3119+ if (isa<PackElementExpr>(E)) {
3120+ Packs.push_back (E);
3121+ }
3122+
3123+ if (auto *declRef = dyn_cast<DeclRefExpr>(E)) {
3124+ auto type = CS.getTypeIfAvailable (declRef);
3125+ if (!type)
3126+ return Action::Continue (E);
3127+
3128+ if (type->is <ElementArchetypeType>() &&
3129+ CS.hasFixFor (CS.getConstraintLocator (declRef),
3130+ FixKind::IgnoreMissingEachKeyword)) {
3131+ Packs.push_back (PackElementExpr::create (CS.getASTContext (),
3132+ /* eachLoc=*/ SourceLoc (),
3133+ declRef,
3134+ /* implicit=*/ true ));
3135+ }
3136+ }
3137+
3138+ return Action::Continue (E);
3139+ }
3140+
3141+ virtual PreWalkAction walkToTypeReprPre (TypeRepr *T) override {
3142+ // Don't walk into nested pack expansions
3143+ if (isa<PackExpansionTypeRepr>(T)) {
3144+ return Action::SkipChildren ();
3145+ }
3146+
3147+ if (isa<PackElementTypeRepr>(T)) {
3148+ Packs.push_back (T);
3149+ }
3150+
3151+ return Action::Continue ();
3152+ }
3153+ } packCollector (CS, packs);
3154+
3155+ expansion->getPatternExpr ()->walk (packCollector);
3156+ }
3157+
30663158 Type visitPackExpansionExpr (PackExpansionExpr *expr) {
30673159 assert (PackElementEnvironments.back () == expr);
30683160 PackElementEnvironments.pop_back ();
@@ -3086,7 +3178,7 @@ namespace {
30863178 // Generate ShapeOf constraints between all packs expanded by this
30873179 // pack expansion expression through the shape type variable.
30883180 SmallVector<ASTNode, 2 > expandedPacks;
3089- expr-> getExpandedPacks ( expandedPacks);
3181+ collectExpandedPacks (expr, expandedPacks);
30903182
30913183 if (expandedPacks.empty ()) {
30923184 (void )CS.recordFix (AllowValueExpansionWithoutPackReferences::create (
@@ -3118,23 +3210,8 @@ namespace {
31183210 }
31193211
31203212 Type visitPackElementExpr (PackElementExpr *expr) {
3121- auto packType = CS.getType (expr->getPackRefExpr ());
3122-
3123- // If 'each t' is written outside of a pack expansion expression, allow the
3124- // type to bind to a hole. The invalid pack reference will be diagnosed when
3125- // attempting to bind the type variable for the underlying pack reference to
3126- // a pack type without TVO_CanBindToPack.
3127- if (PackElementEnvironments.empty ()) {
3128- return CS.createTypeVariable (CS.getConstraintLocator (expr),
3129- TVO_CanBindToHole |
3130- TVO_CanBindToNoEscape);
3131- }
3132-
3133- // The type of a PackElementExpr is the opened pack element archetype
3134- // of the pack reference.
3135- OpenPackElementType openPackElement (CS, CS.getConstraintLocator (expr),
3136- PackElementEnvironments.back ());
3137- return openPackElement (packType, /* packRepr*/ nullptr );
3213+ return openPackElement (CS.getType (expr->getPackRefExpr ()),
3214+ CS.getConstraintLocator (expr));
31383215 }
31393216
31403217 Type visitMaterializePackExpr (MaterializePackExpr *expr) {
0 commit comments