Skip to content

Commit 8975875

Browse files
authored
Merge pull request #23672 from slavapestov/kill-argument-shuffle-expr
Kill ArgumentShuffleExpr
2 parents bf39d72 + 478c133 commit 8975875

27 files changed

+650
-1455
lines changed

include/swift/AST/Expr.h

Lines changed: 80 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,6 @@ class alignas(8) Expr {
296296
NumElements : 16
297297
);
298298

299-
SWIFT_INLINE_BITFIELD_FULL(ArgumentShuffleExpr, ImplicitConversionExpr, 2+16+16+16,
300-
TypeImpact : 2,
301-
: NumPadBits,
302-
NumCallerDefaultArgs : 16,
303-
/// This contains an entry for each element in the Expr type. Each element
304-
/// specifies which index from the SubExpr that the destination element gets.
305-
/// If the element value is DefaultInitialize, then the destination value
306-
/// gets the default initializer for that tuple element value.
307-
NumElementMappings : 16,
308-
/// The arguments that are packed into the variadic element.
309-
NumVariadicArgs : 16
310-
);
311-
312299
SWIFT_INLINE_BITFIELD(ForceValueExpr, Expr, 1,
313300
ForcedIUO : 1
314301
);
@@ -2922,157 +2909,6 @@ class DestructureTupleExpr final : public ImplicitConversionExpr,
29222909
}
29232910
};
29242911

2925-
/// ArgumentShuffleExpr - This represents a "complex" argument list of an
2926-
/// ApplyExpr, with default arguments or varargs.
2927-
///
2928-
/// If hasScalarSource() is true, the subexpression should be treated
2929-
/// as if it were implicitly injected into a single-element tuple
2930-
/// type. Otherwise, the subexpression is known to have a tuple type.
2931-
class ArgumentShuffleExpr final : public ImplicitConversionExpr,
2932-
private llvm::TrailingObjects<ArgumentShuffleExpr, Expr *, int, unsigned> {
2933-
friend TrailingObjects;
2934-
2935-
size_t numTrailingObjects(OverloadToken<Expr *>) const {
2936-
return Bits.ArgumentShuffleExpr.NumCallerDefaultArgs;
2937-
}
2938-
size_t numTrailingObjects(OverloadToken<int>) const {
2939-
return Bits.ArgumentShuffleExpr.NumElementMappings;
2940-
}
2941-
size_t numTrailingObjects(OverloadToken<unsigned>) const {
2942-
return Bits.ArgumentShuffleExpr.NumVariadicArgs;
2943-
}
2944-
2945-
public:
2946-
enum : int {
2947-
/// The element mapping value indicating that a field of the destination
2948-
/// tuple should be default-initialized.
2949-
DefaultInitialize = -1,
2950-
/// The element mapping is part of the variadic field.
2951-
Variadic = -2,
2952-
/// The element mapping value indicating that the field of the
2953-
/// destination tuple should be default-initialized with an expression
2954-
/// provided by the caller.
2955-
/// FIXME: Yet another indication that ArgumentShuffleExpr uses the wrong
2956-
/// formulation.
2957-
CallerDefaultInitialize = -3
2958-
};
2959-
2960-
enum TypeImpact {
2961-
/// The source value is a tuple which is destructured and modified to
2962-
/// create the result, which is a tuple.
2963-
///
2964-
/// Example: (x: Int) => (x: Int, y: Int = 0).
2965-
TupleToTuple,
2966-
2967-
/// The source value is a tuple which is destructured and modified to
2968-
/// create the result, which is a scalar because it has one element and
2969-
/// no labels.
2970-
///
2971-
/// Example: () -> (_: Int = 0)
2972-
/// Another example: (Int, Int) => (_: Int...)
2973-
TupleToScalar,
2974-
2975-
/// The source value is an individual value (possibly one with tuple
2976-
/// type) which is inserted into a particular position in the result,
2977-
/// which is a tuple.
2978-
///
2979-
/// Example: (Int) -> (_: Int, y: Int = 0)
2980-
ScalarToTuple
2981-
2982-
// (ArgumentShuffleExpr are never created for a scalar-to-scalar conversion.)
2983-
};
2984-
2985-
private:
2986-
/// If we're doing a varargs shuffle, this is the array type to build.
2987-
Type VarargsArrayTy;
2988-
2989-
/// If there are any default arguments, the owning function
2990-
/// declaration.
2991-
ConcreteDeclRef DefaultArgsOwner;
2992-
2993-
ArgumentShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
2994-
TypeImpact typeImpact,
2995-
ConcreteDeclRef defaultArgsOwner,
2996-
ArrayRef<unsigned> VariadicArgs,
2997-
Type VarargsArrayTy,
2998-
ArrayRef<Expr *> CallerDefaultArgs,
2999-
Type ty)
3000-
: ImplicitConversionExpr(ExprKind::ArgumentShuffle, subExpr, ty),
3001-
VarargsArrayTy(VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) {
3002-
Bits.ArgumentShuffleExpr.TypeImpact = typeImpact;
3003-
Bits.ArgumentShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size();
3004-
Bits.ArgumentShuffleExpr.NumElementMappings = elementMapping.size();
3005-
Bits.ArgumentShuffleExpr.NumVariadicArgs = VariadicArgs.size();
3006-
std::uninitialized_copy(CallerDefaultArgs.begin(), CallerDefaultArgs.end(),
3007-
getTrailingObjects<Expr*>());
3008-
std::uninitialized_copy(elementMapping.begin(), elementMapping.end(),
3009-
getTrailingObjects<int>());
3010-
std::uninitialized_copy(VariadicArgs.begin(), VariadicArgs.end(),
3011-
getTrailingObjects<unsigned>());
3012-
}
3013-
3014-
public:
3015-
static ArgumentShuffleExpr *create(ASTContext &ctx, Expr *subExpr,
3016-
ArrayRef<int> elementMapping,
3017-
TypeImpact typeImpact,
3018-
ConcreteDeclRef defaultArgsOwner,
3019-
ArrayRef<unsigned> VariadicArgs,
3020-
Type VarargsArrayTy,
3021-
ArrayRef<Expr *> CallerDefaultArgs,
3022-
Type ty);
3023-
3024-
ArrayRef<int> getElementMapping() const {
3025-
return {getTrailingObjects<int>(),
3026-
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumElementMappings)};
3027-
}
3028-
3029-
/// What is the type impact of this shuffle?
3030-
TypeImpact getTypeImpact() const {
3031-
return TypeImpact(Bits.ArgumentShuffleExpr.TypeImpact);
3032-
}
3033-
3034-
bool isSourceScalar() const {
3035-
return getTypeImpact() == ScalarToTuple;
3036-
}
3037-
3038-
bool isResultScalar() const {
3039-
return getTypeImpact() == TupleToScalar;
3040-
}
3041-
3042-
Type getVarargsArrayType() const {
3043-
assert(!VarargsArrayTy.isNull());
3044-
return VarargsArrayTy;
3045-
}
3046-
Type getVarargsArrayTypeOrNull() const {
3047-
return VarargsArrayTy;
3048-
}
3049-
3050-
/// Retrieve the argument indices for the variadic arguments.
3051-
ArrayRef<unsigned> getVariadicArgs() const {
3052-
return {getTrailingObjects<unsigned>(),
3053-
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumVariadicArgs)};
3054-
}
3055-
3056-
/// Retrieve the owner of the default arguments.
3057-
ConcreteDeclRef getDefaultArgsOwner() const { return DefaultArgsOwner; }
3058-
3059-
/// Retrieve the caller-defaulted arguments.
3060-
ArrayRef<Expr *> getCallerDefaultArgs() const {
3061-
return {getTrailingObjects<Expr*>(),
3062-
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumCallerDefaultArgs)};
3063-
}
3064-
3065-
/// Retrieve the caller-defaulted arguments.
3066-
MutableArrayRef<Expr *> getCallerDefaultArgs() {
3067-
return {getTrailingObjects<Expr*>(),
3068-
static_cast<size_t>(Bits.ArgumentShuffleExpr.NumCallerDefaultArgs)};
3069-
}
3070-
3071-
static bool classof(const Expr *E) {
3072-
return E->getKind() == ExprKind::ArgumentShuffle;
3073-
}
3074-
};
3075-
30762912
/// LoadExpr - Turn an l-value into an r-value by performing a "load"
30772913
/// operation. This operation may actually be a logical operation,
30782914
/// i.e. one implemented using a call to a potentially user-defined
@@ -3923,7 +3759,7 @@ class DynamicTypeExpr : public Expr {
39233759
/// Opaque value expressions occur when a particular value within the AST
39243760
/// needs to be re-used without being re-evaluated or for a value that is
39253761
/// a placeholder. OpaqueValueExpr nodes are introduced by some other AST
3926-
/// node (say, a \c DynamicMemberRefExpr) and can only be used within the
3762+
/// node (say, an \c OpenExistentialExpr) and can only be used within the
39273763
/// subexpressions of that AST node.
39283764
class OpaqueValueExpr : public Expr {
39293765
SourceLoc Loc;
@@ -3939,6 +3775,82 @@ class OpaqueValueExpr : public Expr {
39393775
}
39403776
};
39413777

3778+
/// An expression referring to a default argument left unspecified at the
3779+
/// call site.
3780+
///
3781+
/// A DefaultArgumentExpr must only appear as a direct child of a
3782+
/// ParenExpr or a TupleExpr that is itself a call argument.
3783+
class DefaultArgumentExpr final : public Expr {
3784+
/// The owning declaration.
3785+
ConcreteDeclRef DefaultArgsOwner;
3786+
3787+
/// The caller parameter index.
3788+
unsigned ParamIndex;
3789+
3790+
/// The source location of the argument list.
3791+
SourceLoc Loc;
3792+
3793+
public:
3794+
explicit DefaultArgumentExpr(ConcreteDeclRef defaultArgsOwner, unsigned paramIndex,
3795+
SourceLoc loc, Type Ty)
3796+
: Expr(ExprKind::DefaultArgument, /*Implicit=*/true, Ty),
3797+
DefaultArgsOwner(defaultArgsOwner), ParamIndex(paramIndex), Loc(loc) { }
3798+
3799+
SourceRange getSourceRange() const {
3800+
return Loc;
3801+
}
3802+
3803+
ConcreteDeclRef getDefaultArgsOwner() const {
3804+
return DefaultArgsOwner;
3805+
}
3806+
3807+
unsigned getParamIndex() const {
3808+
return ParamIndex;
3809+
}
3810+
3811+
static bool classof(const Expr *E) {
3812+
return E->getKind() == ExprKind::DefaultArgument;
3813+
}
3814+
};
3815+
3816+
/// An expression referring to a caller-side default argument left unspecified
3817+
/// at the call site.
3818+
///
3819+
/// A CallerDefaultArgumentExpr must only appear as a direct child of a
3820+
/// ParenExpr or a TupleExpr that is itself a call argument.
3821+
///
3822+
/// FIXME: This only exists to distinguish caller default arguments from arguments
3823+
/// that were specified at the call site. Once we remove SanitizeExpr, we can remove
3824+
/// this hack too.
3825+
class CallerDefaultArgumentExpr final : public Expr {
3826+
/// The expression that is evaluated to produce the default argument value.
3827+
Expr *SubExpr;
3828+
3829+
/// The source location of the argument list.
3830+
SourceLoc Loc;
3831+
3832+
public:
3833+
explicit CallerDefaultArgumentExpr(Expr *subExpr, SourceLoc loc, Type Ty)
3834+
: Expr(ExprKind::CallerDefaultArgument, /*Implicit=*/true, Ty),
3835+
SubExpr(subExpr), Loc(loc) { }
3836+
3837+
SourceRange getSourceRange() const {
3838+
return Loc;
3839+
}
3840+
3841+
Expr *getSubExpr() const {
3842+
return SubExpr;
3843+
}
3844+
3845+
void setSubExpr(Expr *subExpr) {
3846+
SubExpr = subExpr;
3847+
}
3848+
3849+
static bool classof(const Expr *E) {
3850+
return E->getKind() == ExprKind::CallerDefaultArgument;
3851+
}
3852+
};
3853+
39423854
/// ApplyExpr - Superclass of various function calls, which apply an argument to
39433855
/// a function to get a result.
39443856
class ApplyExpr : public Expr {
@@ -3949,8 +3861,7 @@ class ApplyExpr : public Expr {
39493861
llvm::PointerIntPair<Expr *, 1, bool> ArgAndIsSuper;
39503862

39513863
/// Returns true if \c e could be used as the call's argument. For most \c ApplyExpr
3952-
/// subclasses, this means it is a \c ParenExpr, \c TupleExpr, or
3953-
/// \c ArgumentShuffleExpr.
3864+
/// subclasses, this means it is a \c ParenExpr or \c TupleExpr.
39543865
bool validateArg(Expr *e) const;
39553866

39563867
protected:
@@ -4014,7 +3925,7 @@ class ApplyExpr : public Expr {
40143925
E->getKind() <= ExprKind::Last_ApplyExpr;
40153926
}
40163927
};
4017-
3928+
40183929
/// CallExpr - Application of an argument to a function, which occurs
40193930
/// syntactically through juxtaposition with a TupleExpr whose
40203931
/// leading '(' is unspaced.
@@ -5330,7 +5241,7 @@ inline bool ApplyExpr::validateArg(Expr *e) const {
53305241
else if (isa<BinaryExpr>(this))
53315242
return isa<TupleExpr>(e);
53325243
else
5333-
return isa<ParenExpr>(e) || isa<TupleExpr>(e) || isa<ArgumentShuffleExpr>(e);
5244+
return isa<ParenExpr>(e) || isa<TupleExpr>(e);
53345245
}
53355246

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

include/swift/AST/ExprNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ EXPR(VarargExpansion, Expr)
126126
EXPR(DynamicType, Expr)
127127
EXPR(RebindSelfInConstructor, Expr)
128128
EXPR(OpaqueValue, Expr)
129+
EXPR(DefaultArgument, Expr)
130+
EXPR(CallerDefaultArgument, Expr)
129131
EXPR(BindOptional, Expr)
130132
EXPR(OptionalEvaluation, Expr)
131133
EXPR(ForceValue, Expr)
@@ -144,7 +146,6 @@ ABSTRACT_EXPR(Apply, Expr)
144146
ABSTRACT_EXPR(ImplicitConversion, Expr)
145147
EXPR(Load, ImplicitConversionExpr)
146148
EXPR(DestructureTuple, ImplicitConversionExpr)
147-
EXPR(ArgumentShuffle, ImplicitConversionExpr)
148149
EXPR(UnresolvedTypeConversion, ImplicitConversionExpr)
149150
EXPR(FunctionConversion, ImplicitConversionExpr)
150151
EXPR(CovariantFunctionConversion, ImplicitConversionExpr)

include/swift/Sema/IDETypeChecking.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,25 @@ namespace swift {
202202
/// the decl context.
203203
bool resolveProtocolNames(DeclContext *DC, ArrayRef<const char *> names,
204204
llvm::MapVector<ProtocolDecl*, StringRef> &result);
205+
206+
/// FIXME: All of the below goes away once CallExpr directly stores its
207+
/// arguments.
208+
209+
/// Return value for getOriginalArgumentList().
210+
struct OriginalArgumentList {
211+
SmallVector<Expr *, 4> args;
212+
SmallVector<Identifier, 4> labels;
213+
SmallVector<SourceLoc, 4> labelLocs;
214+
SourceLoc lParenLoc;
215+
SourceLoc rParenLoc;
216+
bool hasTrailingClosure = false;
217+
};
218+
219+
/// When applying a solution to a constraint system, the type checker rewrites
220+
/// argument lists of calls to insert default arguments and collect varargs.
221+
/// Sometimes for diagnostics we want to work on the original argument list as
222+
/// written by the user; this performs the reverse transformation.
223+
OriginalArgumentList getOriginalArgumentList(Expr *expr);
205224
}
206225

207226
#endif

0 commit comments

Comments
 (0)