Skip to content

Commit 1ce283a

Browse files
committed
[Sema] Represent pack element references in pack expansion patterns as
PackElementExpr.
1 parent 8bbc3a7 commit 1ce283a

File tree

9 files changed

+54
-126
lines changed

9 files changed

+54
-126
lines changed

include/swift/AST/Expr.h

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3569,51 +3569,41 @@ class PackElementExpr final : public Expr {
35693569
/// call argument lists, the elements of a tuple value, and the source
35703570
/// of a for-in loop.
35713571
class PackExpansionExpr final : public Expr,
3572-
private llvm::TrailingObjects<PackExpansionExpr,
3573-
OpaqueValueExpr *, Expr *> {
3572+
private llvm::TrailingObjects<PackExpansionExpr, PackElementExpr *> {
35743573
friend TrailingObjects;
35753574

35763575
Expr *PatternExpr;
35773576
SourceLoc DotsLoc;
35783577
GenericEnvironment *Environment;
35793578

35803579
PackExpansionExpr(Expr *patternExpr,
3581-
ArrayRef<OpaqueValueExpr *> opaqueValues,
3582-
ArrayRef<Expr *> bindings,
3580+
ArrayRef<PackElementExpr *> packElements,
35833581
SourceLoc dotsLoc,
35843582
GenericEnvironment *environment,
35853583
bool implicit, Type type)
35863584
: Expr(ExprKind::PackExpansion, implicit, type),
35873585
PatternExpr(patternExpr), DotsLoc(dotsLoc), Environment(environment) {
3588-
assert(opaqueValues.size() == bindings.size());
3589-
Bits.PackExpansionExpr.NumBindings = opaqueValues.size();
3586+
Bits.PackExpansionExpr.NumBindings = packElements.size();
35903587

35913588
assert(Bits.PackExpansionExpr.NumBindings > 0 &&
35923589
"PackExpansionExpr must have pack references");
35933590

3594-
std::uninitialized_copy(opaqueValues.begin(), opaqueValues.end(),
3595-
getTrailingObjects<OpaqueValueExpr *>());
3596-
std::uninitialized_copy(bindings.begin(), bindings.end(),
3597-
getTrailingObjects<Expr *>());
3598-
}
3599-
3600-
size_t numTrailingObjects(OverloadToken<OpaqueValueExpr *>) const {
3601-
return getNumBindings();
3591+
std::uninitialized_copy(packElements.begin(), packElements.end(),
3592+
getTrailingObjects<PackElementExpr *>());
36023593
}
36033594

3604-
size_t numTrailingObjects(OverloadToken<Expr *>) const {
3595+
size_t numTrailingObjects(OverloadToken<PackElementExpr *>) const {
36053596
return getNumBindings();
36063597
}
36073598

3608-
MutableArrayRef<Expr *> getMutableBindings() {
3609-
return {getTrailingObjects<Expr *>(), getNumBindings()};
3599+
MutableArrayRef<PackElementExpr *> getMutableBindings() {
3600+
return {getTrailingObjects<PackElementExpr *>(), getNumBindings()};
36103601
}
36113602

36123603
public:
36133604
static PackExpansionExpr *create(ASTContext &ctx,
36143605
Expr *patternExpr,
3615-
ArrayRef<OpaqueValueExpr *> opaqueValues,
3616-
ArrayRef<Expr *> bindings,
3606+
ArrayRef<PackElementExpr *> packElements,
36173607
SourceLoc dotsLoc,
36183608
GenericEnvironment *environment,
36193609
bool implicit = false,
@@ -3629,15 +3619,11 @@ class PackExpansionExpr final : public Expr,
36293619
return Bits.PackExpansionExpr.NumBindings;
36303620
}
36313621

3632-
ArrayRef<OpaqueValueExpr *> getOpaqueValues() {
3633-
return {getTrailingObjects<OpaqueValueExpr *>(), getNumBindings()};
3634-
}
3635-
3636-
ArrayRef<Expr *> getBindings() {
3637-
return {getTrailingObjects<Expr *>(), getNumBindings()};
3622+
ArrayRef<PackElementExpr *> getPackElements() {
3623+
return {getTrailingObjects<PackElementExpr *>(), getNumBindings()};
36383624
}
36393625

3640-
void setBinding(unsigned i, Expr *e) {
3626+
void setBinding(unsigned i, PackElementExpr *e) {
36413627
getMutableBindings()[i] = e;
36423628
}
36433629

lib/AST/ASTVerifier.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -836,12 +836,6 @@ class Verifier : public ASTWalker {
836836
return false;
837837

838838
Generics.push_back(expr->getGenericEnvironment());
839-
840-
for (auto *placeholder : expr->getOpaqueValues()) {
841-
assert(!OpaqueValues.count(placeholder));
842-
OpaqueValues[placeholder] = 0;
843-
}
844-
845839
return true;
846840
}
847841

@@ -854,13 +848,6 @@ class Verifier : public ASTWalker {
854848
verifyCheckedAlwaysBase(E);
855849
}
856850

857-
void cleanup(PackExpansionExpr *expr) {
858-
for (auto *placeholder : expr->getOpaqueValues()) {
859-
assert(OpaqueValues.count(placeholder));
860-
OpaqueValues.erase(placeholder);
861-
}
862-
}
863-
864851
bool shouldVerify(MakeTemporarilyEscapableExpr *expr) {
865852
if (!shouldVerify(cast<Expr>(expr)))
866853
return false;

lib/AST/Expr.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,16 +1248,14 @@ VarargExpansionExpr *VarargExpansionExpr::createArrayExpansion(ASTContext &ctx,
12481248

12491249
PackExpansionExpr *
12501250
PackExpansionExpr::create(ASTContext &ctx, Expr *patternExpr,
1251-
ArrayRef<OpaqueValueExpr *> opaqueValues,
1252-
ArrayRef<Expr *> bindings, SourceLoc dotsLoc,
1253-
GenericEnvironment *environment,
1251+
ArrayRef<PackElementExpr *> packElements,
1252+
SourceLoc dotsLoc, GenericEnvironment *environment,
12541253
bool implicit, Type type) {
12551254
size_t size =
1256-
totalSizeToAlloc<OpaqueValueExpr *, Expr *>(opaqueValues.size(),
1257-
bindings.size());
1255+
totalSizeToAlloc<PackElementExpr *>(packElements.size());
12581256
void *mem = ctx.Allocate(size, alignof(PackExpansionExpr));
1259-
return ::new (mem) PackExpansionExpr(patternExpr, opaqueValues,
1260-
bindings, dotsLoc, environment,
1257+
return ::new (mem) PackExpansionExpr(patternExpr, packElements,
1258+
dotsLoc, environment,
12611259
implicit, type);
12621260
}
12631261

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,13 +3820,7 @@ namespace {
38203820
}
38213821

38223822
Expr *visitPackExpansionExpr(PackExpansionExpr *expr) {
3823-
for (unsigned i = 0; i < expr->getNumBindings(); ++i) {
3824-
auto *binding = expr->getBindings()[i];
3825-
expr->setBinding(i, visit(binding));
3826-
}
3827-
3828-
simplifyExprType(expr);
3829-
return expr;
3823+
return simplifyExprType(expr);
38303824
}
38313825

38323826
Expr *visitPackElementExpr(PackElementExpr *expr) {
@@ -7136,10 +7130,9 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
71367130
auto shapeType = toExpansionType->getCountType();
71377131
auto expansionTy = PackExpansionType::get(patternType, shapeType);
71387132

7139-
return cs.cacheType(PackExpansionExpr::create(ctx, pattern,
7140-
expansion->getOpaqueValues(), expansion->getBindings(),
7141-
expansion->getEndLoc(), expansion->getGenericEnvironment(),
7142-
expansion->isImplicit(), expansionTy));
7133+
expansion->setPatternExpr(pattern);
7134+
expansion->setType(expansionTy);
7135+
return expansion;
71437136
}
71447137

71457138
case TypeKind::BuiltinTuple:

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2983,7 +2983,7 @@ namespace {
29832983
auto *shapeTypeVar = CS.createTypeVariable(shapeLoc,
29842984
TVO_CanBindToPack |
29852985
TVO_CanBindToHole);
2986-
auto packReference = expr->getBindings().front();
2986+
auto packReference = expr->getPackElements().front()->getPackRefExpr();
29872987
auto packType = CS.simplifyType(CS.getType(packReference))
29882988
->castTo<PackExpansionType>()->getPatternType();
29892989
CS.addConstraint(ConstraintKind::ShapeOf, packType, shapeTypeVar,

lib/Sema/MiscDiagnostics.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,16 +3621,6 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) {
36213621
return markStoredOrInOutExpr(OEE->getSubExpr(), Flags);
36223622
}
36233623

3624-
// Bind pack references in pack expansions.
3625-
if (auto *expansion = dyn_cast<PackExpansionExpr>(E)) {
3626-
for (unsigned i = 0; i < expansion->getNumBindings(); ++i) {
3627-
auto *opaqueValue = expansion->getOpaqueValues()[i];
3628-
auto *packReference = expansion->getBindings()[i];
3629-
OpaqueValueMap[opaqueValue] = packReference;
3630-
}
3631-
return markStoredOrInOutExpr(expansion->getPatternExpr(), Flags);
3632-
}
3633-
36343624
// If this is an OpaqueValueExpr that we've seen a mapping for, jump to the
36353625
// mapped value.
36363626
if (auto *OVE = dyn_cast<OpaqueValueExpr>(E))
@@ -3707,15 +3697,6 @@ ASTWalker::PreWalkResult<Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
37073697
return Action::SkipChildren(E);
37083698
}
37093699

3710-
// If we see a PackExpansionExpr, record its pack reference bindings.
3711-
if (auto *expansion = dyn_cast<PackExpansionExpr>(E)) {
3712-
for (unsigned i = 0; i < expansion->getNumBindings(); ++i) {
3713-
auto *opaqueValue = expansion->getOpaqueValues()[i];
3714-
auto *packReference = expansion->getBindings()[i];
3715-
OpaqueValueMap[opaqueValue] = packReference;
3716-
}
3717-
}
3718-
37193700
// Visit bindings.
37203701
if (auto ove = dyn_cast<OpaqueValueExpr>(E)) {
37213702
if (auto mapping = OpaqueValueMap.lookup(ove))

lib/Sema/PreCheckExpr.cpp

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -402,55 +402,38 @@ static BinaryExpr *getCompositionExpr(Expr *expr) {
402402
static Expr *getPackExpansion(DeclContext *dc, Expr *expr, SourceLoc opLoc) {
403403
struct PackReferenceFinder : public ASTWalker {
404404
DeclContext *dc;
405-
llvm::SmallVector<OpaqueValueExpr *, 2> opaqueValues;
406-
llvm::SmallVector<Expr *, 2> bindings;
405+
llvm::SmallVector<PackElementExpr *, 2> packElements;
407406
GenericEnvironment *environment;
408407

409408
PackReferenceFinder(DeclContext *dc)
410409
: dc(dc), environment(nullptr) {}
411410

412411
virtual PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
413412
auto &ctx = dc->getASTContext();
413+
auto *packElement = dyn_cast<PackElementExpr>(E);
414+
if (!packElement)
415+
return Action::Continue(E);
414416

415-
if (auto *declRef = dyn_cast<DeclRefExpr>(E)) {
416-
auto *decl = dyn_cast<VarDecl>(declRef->getDecl());
417-
if (!decl)
418-
return Action::Continue(E);
419-
420-
if (auto expansionType = decl->getType()->getAs<PackExpansionType>()) {
421-
auto sourceRange = declRef->getSourceRange();
422-
423-
// Map the pattern interface type into the context of the opened
424-
// element signature.
425-
if (!environment) {
426-
auto sig = ctx.getOpenedElementSignature(
427-
dc->getGenericSignatureOfContext().getCanonicalSignature());
428-
auto *contextEnv = dc->getGenericEnvironmentOfContext();
429-
auto contextSubs = contextEnv->getForwardingSubstitutionMap();
430-
environment =
431-
GenericEnvironment::forOpenedElement(sig, UUID::fromTime(),
432-
contextSubs);
433-
}
434-
auto elementType = environment->mapPackTypeIntoElementContext(
435-
expansionType->getPatternType()->mapTypeOutOfContext());
436-
437-
auto *opaqueValue = new (ctx) OpaqueValueExpr(sourceRange, elementType);
438-
opaqueValues.push_back(opaqueValue);
439-
bindings.push_back(declRef);
440-
return Action::Continue(opaqueValue);
441-
}
417+
if (!environment) {
418+
auto sig = ctx.getOpenedElementSignature(
419+
dc->getGenericSignatureOfContext().getCanonicalSignature());
420+
auto *contextEnv = dc->getGenericEnvironmentOfContext();
421+
auto contextSubs = contextEnv->getForwardingSubstitutionMap();
422+
environment =
423+
GenericEnvironment::forOpenedElement(sig, UUID::fromTime(),
424+
contextSubs);
442425
}
443426

444-
return Action::Continue(E);
427+
packElements.push_back(packElement);
428+
return Action::Continue(packElement);
445429
}
446430
} packReferenceFinder(dc);
447431

448432
auto *pattern = expr->walk(packReferenceFinder);
449433

450-
if (!packReferenceFinder.bindings.empty()) {
434+
if (!packReferenceFinder.packElements.empty()) {
451435
return PackExpansionExpr::create(dc->getASTContext(), pattern,
452-
packReferenceFinder.opaqueValues,
453-
packReferenceFinder.bindings,
436+
packReferenceFinder.packElements,
454437
opLoc, packReferenceFinder.environment);
455438
}
456439

test/Constraints/pack-expansion-expressions.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,44 @@
33
// REQUIRES: asserts
44

55
func tuplify<T...>(_ t: T...) -> (T...) {
6-
return (t...)
6+
return ((each t)...)
77
}
88

99
func prepend<First, Rest...>(value: First, to rest: Rest...) -> (First, Rest...) {
10-
return (value, rest...)
10+
return (value, (each rest)...)
1111
}
1212

1313
func concatenate<T..., U...>(_ first: T..., with second: U...) -> (T..., U...) {
14-
return (first..., second...)
14+
return ((each first)..., (each second)...)
1515
}
1616

1717
func zip<T..., U...>(_ first: T..., with second: U...) -> ((T, U)...) {
18-
return ((first, second)...)
18+
return ((each first, each second)...)
1919
}
2020

2121
func forward<U...>(_ u: U...) -> (U...) {
22-
return tuplify(u...)
22+
return tuplify((each u)...)
2323
}
2424

2525
func forwardAndMap<U..., V...>(us u: U..., vs v: V...) -> ([(U, V)]...) {
26-
return tuplify([(u, v)]...)
26+
return tuplify([(each u, each v)]...)
2727
}
2828

2929
func variadicMap<T..., Result...>(_ t: T..., transform: ((T) -> Result)...) -> (Result...) {
30-
return (transform(t)...)
30+
return ((each transform)(each t)...)
3131
}
3232

3333
func coerceExpansion<T...>(_ value: T...) {
3434
func promoteToOptional<Wrapped...>(_: Wrapped?...) {}
3535

36-
promoteToOptional(value...)
36+
promoteToOptional((each value)...)
3737
}
3838

3939
func localValuePack<T...>(_ t: T...) -> (T..., T...) {
40-
let local = t...
41-
let localAnnotated: T... = t...
40+
let local = (each t)...
41+
let localAnnotated: T... = (each t)...
4242

43-
return (local..., localAnnotated...)
43+
return ((each local)..., (each localAnnotated)...)
4444
}
4545

4646
protocol P {
@@ -52,14 +52,14 @@ protocol P {
5252
}
5353

5454
func outerArchetype<T..., U>(t: T..., u: U) where T: P {
55-
let _: (T.A, U)... = (t.value, u)...
55+
let _: (T.A, U)... = ((each t).value, u)...
5656
}
5757

5858
func sameElement<T..., U>(t: T..., u: U) where T: P, T == U {
59-
let _: T... = t.f(u)...
59+
let _: T... = (each t).f(u)...
6060
}
6161

6262
func forEachEach<C..., U>(c: C..., function: (U) -> Void)
6363
where C: Collection, C.Element == U {
64-
_ = c.forEach(function)...
64+
_ = (each c).forEach(function)...
6565
}

test/Constraints/variadic_generic_constraints.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ let _ = zip(t: 1, 2, 3, u: "hi", "hello", "greetings") // ok
6969
let _ = zip(t: 1, u: "hi", "hello", "greetings") // expected-error {{type of expression is ambiguous without more context}}
7070

7171
func goodCallToZip<T..., U...>(t: T..., u: U...) where ((T, U)...): Any {
72-
_ = zip(t: t..., u: u...)
72+
_ = zip(t: (each t)..., u: (each u)...)
7373
}
7474

7575
func badCallToZip<T..., U...>(t: T..., u: U...) {
76-
_ = zip(t: t..., u: u...)
76+
_ = zip(t: (each t)..., u: (each u)...)
7777
// expected-error@-1 {{global function 'zip(t:u:)' requires the type packs 'T' and 'U' have the same shape}}
7878
}

0 commit comments

Comments
 (0)