Skip to content

Commit f157cdc

Browse files
authored
Merge pull request #23458 from slavapestov/tuple-conversions-part-1
Split off ArgumentShuffleExpr from TupleShuffleExpr
2 parents 2ebd24b + 428c709 commit f157cdc

19 files changed

+259
-199
lines changed

include/swift/AST/Expr.h

Lines changed: 83 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,13 @@ class alignas(8) Expr {
290290

291291
SWIFT_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr);
292292

293-
SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 2+16+16+16,
293+
SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 16,
294+
/// This contains an entry for each element in the Expr type. Each element
295+
/// specifies which index from the SubExpr that the destination element gets.
296+
NumElementMappings : 16
297+
);
298+
299+
SWIFT_INLINE_BITFIELD_FULL(ArgumentShuffleExpr, ImplicitConversionExpr, 2+16+16+16,
294300
TypeImpact : 2,
295301
: NumPadBits,
296302
NumCallerDefaultArgs : 16,
@@ -2956,22 +2962,56 @@ class UnevaluatedInstanceExpr : public ImplicitConversionExpr {
29562962

29572963
/// TupleShuffleExpr - This represents a permutation of a tuple value to a new
29582964
/// tuple type.
2965+
class TupleShuffleExpr final : public ImplicitConversionExpr,
2966+
private llvm::TrailingObjects<TupleShuffleExpr, unsigned> {
2967+
friend TrailingObjects;
2968+
2969+
size_t numTrailingObjects(OverloadToken<unsigned>) const {
2970+
return Bits.TupleShuffleExpr.NumElementMappings;
2971+
}
2972+
2973+
private:
2974+
TupleShuffleExpr(Expr *subExpr, ArrayRef<unsigned> elementMapping,
2975+
Type ty)
2976+
: ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty) {
2977+
Bits.TupleShuffleExpr.NumElementMappings = elementMapping.size();
2978+
std::uninitialized_copy(elementMapping.begin(), elementMapping.end(),
2979+
getTrailingObjects<unsigned>());
2980+
}
2981+
2982+
public:
2983+
static TupleShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
2984+
ArrayRef<unsigned> elementMapping,
2985+
Type ty);
2986+
2987+
ArrayRef<unsigned> getElementMapping() const {
2988+
return {getTrailingObjects<unsigned>(),
2989+
static_cast<size_t>(Bits.TupleShuffleExpr.NumElementMappings)};
2990+
}
2991+
2992+
static bool classof(const Expr *E) {
2993+
return E->getKind() == ExprKind::TupleShuffle;
2994+
}
2995+
};
2996+
2997+
/// ArgumentShuffleExpr - This represents a "complex" argument list of an
2998+
/// ApplyExpr, with default arguments or varargs.
29592999
///
29603000
/// If hasScalarSource() is true, the subexpression should be treated
29613001
/// as if it were implicitly injected into a single-element tuple
29623002
/// type. Otherwise, the subexpression is known to have a tuple type.
2963-
class TupleShuffleExpr final : public ImplicitConversionExpr,
2964-
private llvm::TrailingObjects<TupleShuffleExpr, Expr *, int, unsigned> {
3003+
class ArgumentShuffleExpr final : public ImplicitConversionExpr,
3004+
private llvm::TrailingObjects<ArgumentShuffleExpr, Expr *, int, unsigned> {
29653005
friend TrailingObjects;
29663006

29673007
size_t numTrailingObjects(OverloadToken<Expr *>) const {
2968-
return Bits.TupleShuffleExpr.NumCallerDefaultArgs;
3008+
return Bits.ArgumentShuffleExpr.NumCallerDefaultArgs;
29693009
}
29703010
size_t numTrailingObjects(OverloadToken<int>) const {
2971-
return Bits.TupleShuffleExpr.NumElementMappings;
3011+
return Bits.ArgumentShuffleExpr.NumElementMappings;
29723012
}
29733013
size_t numTrailingObjects(OverloadToken<unsigned>) const {
2974-
return Bits.TupleShuffleExpr.NumVariadicArgs;
3014+
return Bits.ArgumentShuffleExpr.NumVariadicArgs;
29753015
}
29763016

29773017
public:
@@ -2984,27 +3024,34 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
29843024
/// The element mapping value indicating that the field of the
29853025
/// destination tuple should be default-initialized with an expression
29863026
/// provided by the caller.
2987-
/// FIXME: Yet another indication that TupleShuffleExpr uses the wrong
3027+
/// FIXME: Yet another indication that ArgumentShuffleExpr uses the wrong
29883028
/// formulation.
29893029
CallerDefaultInitialize = -3
29903030
};
29913031

29923032
enum TypeImpact {
29933033
/// The source value is a tuple which is destructured and modified to
29943034
/// create the result, which is a tuple.
3035+
///
3036+
/// Example: (x: Int) => (x: Int, y: Int = 0).
29953037
TupleToTuple,
29963038

29973039
/// The source value is a tuple which is destructured and modified to
29983040
/// create the result, which is a scalar because it has one element and
29993041
/// no labels.
3042+
///
3043+
/// Example: () -> (_: Int = 0)
3044+
/// Another example: (Int, Int) => (_: Int...)
30003045
TupleToScalar,
30013046

30023047
/// The source value is an individual value (possibly one with tuple
30033048
/// type) which is inserted into a particular position in the result,
30043049
/// which is a tuple.
3050+
///
3051+
/// Example: (Int) -> (_: Int, y: Int = 0)
30053052
ScalarToTuple
30063053

3007-
// (TupleShuffleExprs are never created for a scalar-to-scalar conversion.)
3054+
// (ArgumentShuffleExpr are never created for a scalar-to-scalar conversion.)
30083055
};
30093056

30103057
private:
@@ -3015,19 +3062,19 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
30153062
/// declaration.
30163063
ConcreteDeclRef DefaultArgsOwner;
30173064

3018-
TupleShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
3019-
TypeImpact typeImpact,
3020-
ConcreteDeclRef defaultArgsOwner,
3021-
ArrayRef<unsigned> VariadicArgs,
3022-
Type VarargsArrayTy,
3023-
ArrayRef<Expr *> CallerDefaultArgs,
3024-
Type ty)
3025-
: ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty),
3065+
ArgumentShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
3066+
TypeImpact typeImpact,
3067+
ConcreteDeclRef defaultArgsOwner,
3068+
ArrayRef<unsigned> VariadicArgs,
3069+
Type VarargsArrayTy,
3070+
ArrayRef<Expr *> CallerDefaultArgs,
3071+
Type ty)
3072+
: ImplicitConversionExpr(ExprKind::ArgumentShuffle, subExpr, ty),
30263073
VarargsArrayTy(VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) {
3027-
Bits.TupleShuffleExpr.TypeImpact = typeImpact;
3028-
Bits.TupleShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size();
3029-
Bits.TupleShuffleExpr.NumElementMappings = elementMapping.size();
3030-
Bits.TupleShuffleExpr.NumVariadicArgs = VariadicArgs.size();
3074+
Bits.ArgumentShuffleExpr.TypeImpact = typeImpact;
3075+
Bits.ArgumentShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size();
3076+
Bits.ArgumentShuffleExpr.NumElementMappings = elementMapping.size();
3077+
Bits.ArgumentShuffleExpr.NumVariadicArgs = VariadicArgs.size();
30313078
std::uninitialized_copy(CallerDefaultArgs.begin(), CallerDefaultArgs.end(),
30323079
getTrailingObjects<Expr*>());
30333080
std::uninitialized_copy(elementMapping.begin(), elementMapping.end(),
@@ -3037,23 +3084,23 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
30373084
}
30383085

30393086
public:
3040-
static TupleShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
3041-
ArrayRef<int> elementMapping,
3042-
TypeImpact typeImpact,
3043-
ConcreteDeclRef defaultArgsOwner,
3044-
ArrayRef<unsigned> VariadicArgs,
3045-
Type VarargsArrayTy,
3046-
ArrayRef<Expr *> CallerDefaultArgs,
3047-
Type ty);
3087+
static ArgumentShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
3088+
ArrayRef<int> elementMapping,
3089+
TypeImpact typeImpact,
3090+
ConcreteDeclRef defaultArgsOwner,
3091+
ArrayRef<unsigned> VariadicArgs,
3092+
Type VarargsArrayTy,
3093+
ArrayRef<Expr *> CallerDefaultArgs,
3094+
Type ty);
30483095

30493096
ArrayRef<int> getElementMapping() const {
30503097
return {getTrailingObjects<int>(),
3051-
static_cast<size_t>(Bits.TupleShuffleExpr.NumElementMappings)};
3098+
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumElementMappings)};
30523099
}
30533100

30543101
/// What is the type impact of this shuffle?
30553102
TypeImpact getTypeImpact() const {
3056-
return TypeImpact(Bits.TupleShuffleExpr.TypeImpact);
3103+
return TypeImpact(Bits.ArgumentShuffleExpr.TypeImpact);
30573104
}
30583105

30593106
bool isSourceScalar() const {
@@ -3075,7 +3122,7 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
30753122
/// Retrieve the argument indices for the variadic arguments.
30763123
ArrayRef<unsigned> getVariadicArgs() const {
30773124
return {getTrailingObjects<unsigned>(),
3078-
static_cast<size_t>(Bits.TupleShuffleExpr.NumVariadicArgs)};
3125+
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumVariadicArgs)};
30793126
}
30803127

30813128
/// Retrieve the owner of the default arguments.
@@ -3084,17 +3131,17 @@ class TupleShuffleExpr final : public ImplicitConversionExpr,
30843131
/// Retrieve the caller-defaulted arguments.
30853132
ArrayRef<Expr *> getCallerDefaultArgs() const {
30863133
return {getTrailingObjects<Expr*>(),
3087-
static_cast<size_t>(Bits.TupleShuffleExpr.NumCallerDefaultArgs)};
3134+
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumCallerDefaultArgs)};
30883135
}
30893136

30903137
/// Retrieve the caller-defaulted arguments.
30913138
MutableArrayRef<Expr *> getCallerDefaultArgs() {
30923139
return {getTrailingObjects<Expr*>(),
3093-
static_cast<size_t>(Bits.TupleShuffleExpr.NumCallerDefaultArgs)};
3140+
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumCallerDefaultArgs)};
30943141
}
30953142

30963143
static bool classof(const Expr *E) {
3097-
return E->getKind() == ExprKind::TupleShuffle;
3144+
return E->getKind() == ExprKind::ArgumentShuffle;
30983145
}
30993146
};
31003147

@@ -3975,7 +4022,7 @@ class ApplyExpr : public Expr {
39754022

39764023
/// Returns true if \c e could be used as the call's argument. For most \c ApplyExpr
39774024
/// subclasses, this means it is a \c ParenExpr, \c TupleExpr, or
3978-
/// \c TupleShuffleExpr.
4025+
/// \c ArgumentShuffleExpr.
39794026
bool validateArg(Expr *e) const;
39804027

39814028
protected:
@@ -5355,7 +5402,7 @@ inline bool ApplyExpr::validateArg(Expr *e) const {
53555402
else if (isa<BinaryExpr>(this))
53565403
return isa<TupleExpr>(e);
53575404
else
5358-
return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<TupleShuffleExpr>(e);
5405+
return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<ArgumentShuffleExpr>(e);
53595406
}
53605407

53615408
inline Expr *const *CollectionExpr::getTrailingObjectsPointer() const {

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ ABSTRACT_EXPR(Apply, Expr)
144144
ABSTRACT_EXPR(ImplicitConversion, Expr)
145145
EXPR(Load, ImplicitConversionExpr)
146146
EXPR(TupleShuffle, ImplicitConversionExpr)
147+
EXPR(ArgumentShuffle, ImplicitConversionExpr)
147148
EXPR(UnresolvedTypeConversion, ImplicitConversionExpr)
148149
EXPR(FunctionConversion, ImplicitConversionExpr)
149150
EXPR(CovariantFunctionConversion, ImplicitConversionExpr)

lib/AST/ASTDumper.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,15 +2118,26 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
21182118
PrintWithColorRAII(OS, ParenthesisColor) << ')';
21192119
}
21202120
void visitTupleShuffleExpr(TupleShuffleExpr *E) {
2121+
printCommon(E, "tuple_shuffle_expr");
2122+
OS << " elements=[";
2123+
for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) {
2124+
if (i) OS << ", ";
2125+
OS << E->getElementMapping()[i];
2126+
}
2127+
OS << "]\n";
2128+
printRec(E->getSubExpr());
2129+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2130+
}
2131+
void visitArgumentShuffleExpr(ArgumentShuffleExpr *E) {
21212132
printCommon(E, "tuple_shuffle_expr");
21222133
switch (E->getTypeImpact()) {
2123-
case TupleShuffleExpr::ScalarToTuple:
2134+
case ArgumentShuffleExpr::ScalarToTuple:
21242135
OS << " scalar_to_tuple";
21252136
break;
2126-
case TupleShuffleExpr::TupleToTuple:
2137+
case ArgumentShuffleExpr::TupleToTuple:
21272138
OS << " tuple_to_tuple";
21282139
break;
2129-
case TupleShuffleExpr::TupleToScalar:
2140+
case ArgumentShuffleExpr::TupleToScalar:
21302141
OS << " tuple_to_scalar";
21312142
break;
21322143
}

lib/AST/ASTVerifier.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,10 +1709,10 @@ class Verifier : public ASTWalker {
17091709
}
17101710
};
17111711

1712-
// If we have a tuple_shuffle, strip it off. We want to visit the
1712+
// If we have an argument shuffle, strip it off. We want to visit the
17131713
// underlying paren or tuple expr.
1714-
if (auto *TupleShuffle = dyn_cast<TupleShuffleExpr>(Arg)) {
1715-
Arg = TupleShuffle->getSubExpr();
1714+
if (auto *ArgShuffle = dyn_cast<ArgumentShuffleExpr>(Arg)) {
1715+
Arg = ArgShuffle->getSubExpr();
17161716
}
17171717

17181718
if (auto *ParentExprArg = dyn_cast<ParenExpr>(Arg)) {
@@ -1991,6 +1991,30 @@ class Verifier : public ASTWalker {
19911991
void verifyChecked(TupleShuffleExpr *E) {
19921992
PrettyStackTraceExpr debugStack(Ctx, "verifying TupleShuffleExpr", E);
19931993

1994+
auto getSubElementType = [&](unsigned i) {
1995+
return (E->getSubExpr()->getType()->castTo<TupleType>()
1996+
->getElementType(i));
1997+
};
1998+
1999+
/// Retrieve the ith element type from the resulting tuple type.
2000+
auto getOuterElementType = [&](unsigned i) -> Type {
2001+
return E->getType()->castTo<TupleType>()->getElementType(i);
2002+
};
2003+
2004+
for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) {
2005+
int subElem = E->getElementMapping()[i];
2006+
if (!getOuterElementType(i)->isEqual(getSubElementType(subElem))) {
2007+
Out << "Type mismatch in TupleShuffleExpr\n";
2008+
abort();
2009+
}
2010+
}
2011+
2012+
verifyCheckedBase(E);
2013+
}
2014+
2015+
void verifyChecked(ArgumentShuffleExpr *E) {
2016+
PrettyStackTraceExpr debugStack(Ctx, "verifying ArgumentShuffleExpr", E);
2017+
19942018
auto getSubElementType = [&](unsigned i) {
19952019
if (E->isSourceScalar()) {
19962020
assert(i == 0);
@@ -2015,30 +2039,30 @@ class Verifier : public ASTWalker {
20152039
unsigned callerDefaultArgIndex = 0;
20162040
for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) {
20172041
int subElem = E->getElementMapping()[i];
2018-
if (subElem == TupleShuffleExpr::DefaultInitialize)
2042+
if (subElem == ArgumentShuffleExpr::DefaultInitialize)
20192043
continue;
2020-
if (subElem == TupleShuffleExpr::Variadic) {
2044+
if (subElem == ArgumentShuffleExpr::Variadic) {
20212045
varargsType = (E->getType()->castTo<TupleType>()
20222046
->getElement(i).getVarargBaseTy());
20232047
break;
20242048
}
2025-
if (subElem == TupleShuffleExpr::CallerDefaultInitialize) {
2049+
if (subElem == ArgumentShuffleExpr::CallerDefaultInitialize) {
20262050
auto init = E->getCallerDefaultArgs()[callerDefaultArgIndex++];
20272051
if (!getOuterElementType(i)->isEqual(init->getType())) {
2028-
Out << "Type mismatch in TupleShuffleExpr\n";
2052+
Out << "Type mismatch in ArgumentShuffleExpr\n";
20292053
abort();
20302054
}
20312055
continue;
20322056
}
20332057
if (!getOuterElementType(i)->isEqual(getSubElementType(subElem))) {
2034-
Out << "Type mismatch in TupleShuffleExpr\n";
2058+
Out << "Type mismatch in ArgumentShuffleExpr\n";
20352059
abort();
20362060
}
20372061
}
20382062
if (varargsType) {
20392063
for (auto sourceIdx : E->getVariadicArgs()) {
20402064
if (!getSubElementType(sourceIdx)->isEqual(varargsType)) {
2041-
Out << "Vararg type mismatch in TupleShuffleExpr\n";
2065+
Out << "Vararg type mismatch in ArgumentShuffleExpr\n";
20422066
abort();
20432067
}
20442068
}

lib/AST/ASTWalker.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,16 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
646646
return nullptr;
647647
}
648648

649+
return E;
650+
}
651+
652+
Expr *visitArgumentShuffleExpr(ArgumentShuffleExpr *E) {
653+
if (Expr *E2 = doIt(E->getSubExpr())) {
654+
E->setSubExpr(E2);
655+
} else {
656+
return nullptr;
657+
}
658+
649659
for (auto &defaultArg : E->getCallerDefaultArgs()) {
650660
if (Expr *newDefaultArg = doIt(defaultArg))
651661
defaultArg = newDefaultArg;

0 commit comments

Comments
 (0)