Skip to content

Commit 7b35e85

Browse files
committed
[PreCheckExpr] Consider postfix ellipsis expressions containing 'each' type
reprs to be pack expansion expressions.
1 parent 27aa365 commit 7b35e85

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-14
lines changed

include/swift/AST/Expr.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3584,10 +3584,6 @@ class PackExpansionExpr final : public Expr,
35843584
: Expr(ExprKind::PackExpansion, implicit, type),
35853585
PatternExpr(patternExpr), DotsLoc(dotsLoc), Environment(environment) {
35863586
Bits.PackExpansionExpr.NumBindings = packElements.size();
3587-
3588-
assert(Bits.PackExpansionExpr.NumBindings > 0 &&
3589-
"PackExpansionExpr must have pack references");
3590-
35913587
std::uninitialized_copy(packElements.begin(), packElements.end(),
35923588
getTrailingObjects<PackElementExpr *>());
35933589
}

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/ASTWalker.h"
2424
#include "swift/AST/Expr.h"
2525
#include "swift/AST/GenericSignature.h"
26+
#include "swift/AST/GenericEnvironment.h"
2627
#include "swift/AST/ParameterList.h"
2728
#include "swift/AST/PrettyStackTrace.h"
2829
#include "swift/AST/SubstitutionMap.h"
@@ -3006,9 +3007,17 @@ namespace {
30063007
auto *shapeTypeVar = CS.createTypeVariable(shapeLoc,
30073008
TVO_CanBindToPack |
30083009
TVO_CanBindToHole);
3009-
auto packReference = expr->getPackElements().front()->getPackRefExpr();
3010-
auto packType = CS.simplifyType(CS.getType(packReference))
3011-
->castTo<PackExpansionType>()->getPatternType();
3010+
Type packType;
3011+
if (!expr->getPackElements().empty()) {
3012+
auto packReference = expr->getPackElements().front()->getPackRefExpr();
3013+
packType = CS.simplifyType(CS.getType(packReference))
3014+
->castTo<PackExpansionType>()->getPatternType();
3015+
} else {
3016+
// FIXME: The generic environment needs to be per-shape-class.
3017+
llvm::SmallVector<GenericEnvironment::PackElementBinding, 2> bindings;
3018+
elementEnv->getPackElementBindings(bindings);
3019+
packType = bindings.front().second;
3020+
}
30123021
CS.addConstraint(ConstraintKind::ShapeOf, packType, shapeTypeVar,
30133022
CS.getConstraintLocator(expr));
30143023

lib/Sema/PreCheckExpr.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,9 @@ static Expr *getPackExpansion(DeclContext *dc, Expr *expr, SourceLoc opLoc) {
408408
PackReferenceFinder(DeclContext *dc)
409409
: dc(dc), environment(nullptr) {}
410410

411-
virtual PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
412-
auto &ctx = dc->getASTContext();
413-
auto *packElement = dyn_cast<PackElementExpr>(E);
414-
if (!packElement)
415-
return Action::Continue(E);
416-
411+
void createElementEnvironment() {
417412
if (!environment) {
413+
auto &ctx = dc->getASTContext();
418414
auto sig = ctx.getOpenedElementSignature(
419415
dc->getGenericSignatureOfContext().getCanonicalSignature());
420416
auto *contextEnv = dc->getGenericEnvironmentOfContext();
@@ -423,15 +419,30 @@ static Expr *getPackExpansion(DeclContext *dc, Expr *expr, SourceLoc opLoc) {
423419
GenericEnvironment::forOpenedElement(sig, UUID::fromTime(),
424420
contextSubs);
425421
}
422+
}
426423

424+
virtual PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
425+
auto *packElement = dyn_cast<PackElementExpr>(E);
426+
if (!packElement)
427+
return Action::Continue(E);
428+
429+
createElementEnvironment();
427430
packElements.push_back(packElement);
428431
return Action::Continue(packElement);
429432
}
433+
434+
virtual PreWalkAction walkToTypeReprPre(TypeRepr *T) override {
435+
if (isa<PackReferenceTypeRepr>(T)) {
436+
createElementEnvironment();
437+
}
438+
439+
return Action::Continue();
440+
}
430441
} packReferenceFinder(dc);
431442

432443
auto *pattern = expr->walk(packReferenceFinder);
433444

434-
if (!packReferenceFinder.packElements.empty()) {
445+
if (packReferenceFinder.environment != nullptr) {
435446
return PackExpansionExpr::create(dc->getASTContext(), pattern,
436447
packReferenceFinder.packElements,
437448
opLoc, packReferenceFinder.environment);

test/Constraints/pack-expansion-expressions.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,8 @@ func forEachEach<C..., U>(c: C..., function: (U) -> Void)
6363
where C: Collection, C.Element == U {
6464
_ = (each c).forEach(function)...
6565
}
66+
67+
func typeReprPacks<T...>(_ t: T...) where T: ExpressibleByIntegerLiteral {
68+
_ = Array<each T>()...
69+
_ = (1 as each T)...
70+
}

0 commit comments

Comments
 (0)