From 428c7094918cf3c15cb0d233849ebaced211b3ff Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 21 Mar 2019 01:28:30 -0400 Subject: [PATCH] AST: Remove argument list-specific parts of TupleShuffleExpr Before extending TupleShuffleExpr to represent all tuple conversions allowed by the constraint solver, remove the parts of TupleShuffleExpr that are no longer needed; this is support for default arguments, varargs, and scalar-to-tuple and tuple-to-scalar conversions. --- include/swift/AST/Expr.h | 135 +++----------------------------------- lib/AST/ASTDumper.cpp | 27 +------- lib/AST/ASTVerifier.cpp | 41 +----------- lib/AST/ASTWalker.cpp | 7 -- lib/AST/Expr.cpp | 15 +---- lib/SILGen/SILGenExpr.cpp | 37 ++--------- lib/Sema/CSApply.cpp | 15 +---- 7 files changed, 24 insertions(+), 253 deletions(-) diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index de8fce56f7188..2fe2b97aa0e32 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -290,17 +290,10 @@ class alignas(8) Expr { SWIFT_INLINE_BITFIELD_EMPTY(ImplicitConversionExpr, Expr); - SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 2+16+16+16, - TypeImpact : 2, - : NumPadBits, - NumCallerDefaultArgs : 16, + SWIFT_INLINE_BITFIELD_FULL(TupleShuffleExpr, ImplicitConversionExpr, 16, /// This contains an entry for each element in the Expr type. Each element /// specifies which index from the SubExpr that the destination element gets. - /// If the element value is DefaultInitialize, then the destination value - /// gets the default initializer for that tuple element value. - NumElementMappings : 16, - /// The arguments that are packed into the variadic element. - NumVariadicArgs : 16 + NumElementMappings : 16 ); SWIFT_INLINE_BITFIELD_FULL(ArgumentShuffleExpr, ImplicitConversionExpr, 2+16+16+16, @@ -2969,141 +2962,31 @@ class UnevaluatedInstanceExpr : public ImplicitConversionExpr { /// TupleShuffleExpr - This represents a permutation of a tuple value to a new /// tuple type. -/// -/// If hasScalarSource() is true, the subexpression should be treated -/// as if it were implicitly injected into a single-element tuple -/// type. Otherwise, the subexpression is known to have a tuple type. class TupleShuffleExpr final : public ImplicitConversionExpr, - private llvm::TrailingObjects { + private llvm::TrailingObjects { friend TrailingObjects; - size_t numTrailingObjects(OverloadToken) const { - return Bits.TupleShuffleExpr.NumCallerDefaultArgs; - } - size_t numTrailingObjects(OverloadToken) const { - return Bits.TupleShuffleExpr.NumElementMappings; - } size_t numTrailingObjects(OverloadToken) const { - return Bits.TupleShuffleExpr.NumVariadicArgs; + return Bits.TupleShuffleExpr.NumElementMappings; } -public: - enum : int { - /// The element mapping value indicating that a field of the destination - /// tuple should be default-initialized. - DefaultInitialize = -1, - /// The element mapping is part of the variadic field. - Variadic = -2, - /// The element mapping value indicating that the field of the - /// destination tuple should be default-initialized with an expression - /// provided by the caller. - /// FIXME: Yet another indication that TupleShuffleExpr uses the wrong - /// formulation. - CallerDefaultInitialize = -3 - }; - - enum TypeImpact { - /// The source value is a tuple which is destructured and modified to - /// create the result, which is a tuple. - TupleToTuple, - - /// The source value is a tuple which is destructured and modified to - /// create the result, which is a scalar because it has one element and - /// no labels. - TupleToScalar, - - /// The source value is an individual value (possibly one with tuple - /// type) which is inserted into a particular position in the result, - /// which is a tuple. - ScalarToTuple - - // (TupleShuffleExprs are never created for a scalar-to-scalar conversion.) - }; - private: - /// If we're doing a varargs shuffle, this is the array type to build. - Type VarargsArrayTy; - - /// If there are any default arguments, the owning function - /// declaration. - ConcreteDeclRef DefaultArgsOwner; - - TupleShuffleExpr(Expr *subExpr, ArrayRef elementMapping, - TypeImpact typeImpact, - ConcreteDeclRef defaultArgsOwner, - ArrayRef VariadicArgs, - Type VarargsArrayTy, - ArrayRef CallerDefaultArgs, + TupleShuffleExpr(Expr *subExpr, ArrayRef elementMapping, Type ty) - : ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty), - VarargsArrayTy(VarargsArrayTy), DefaultArgsOwner(defaultArgsOwner) { - Bits.TupleShuffleExpr.TypeImpact = typeImpact; - Bits.TupleShuffleExpr.NumCallerDefaultArgs = CallerDefaultArgs.size(); + : ImplicitConversionExpr(ExprKind::TupleShuffle, subExpr, ty) { Bits.TupleShuffleExpr.NumElementMappings = elementMapping.size(); - Bits.TupleShuffleExpr.NumVariadicArgs = VariadicArgs.size(); - std::uninitialized_copy(CallerDefaultArgs.begin(), CallerDefaultArgs.end(), - getTrailingObjects()); std::uninitialized_copy(elementMapping.begin(), elementMapping.end(), - getTrailingObjects()); - std::uninitialized_copy(VariadicArgs.begin(), VariadicArgs.end(), getTrailingObjects()); } public: static TupleShuffleExpr *create(ASTContext &ctx, Expr *subExpr, - ArrayRef elementMapping, - TypeImpact typeImpact, - ConcreteDeclRef defaultArgsOwner, - ArrayRef VariadicArgs, - Type VarargsArrayTy, - ArrayRef CallerDefaultArgs, + ArrayRef elementMapping, Type ty); - ArrayRef getElementMapping() const { - return {getTrailingObjects(), - static_cast(Bits.TupleShuffleExpr.NumElementMappings)}; - } - - /// What is the type impact of this shuffle? - TypeImpact getTypeImpact() const { - return TypeImpact(Bits.TupleShuffleExpr.TypeImpact); - } - - bool isSourceScalar() const { - return getTypeImpact() == ScalarToTuple; - } - - bool isResultScalar() const { - return getTypeImpact() == TupleToScalar; - } - - Type getVarargsArrayType() const { - assert(!VarargsArrayTy.isNull()); - return VarargsArrayTy; - } - Type getVarargsArrayTypeOrNull() const { - return VarargsArrayTy; - } - - /// Retrieve the argument indices for the variadic arguments. - ArrayRef getVariadicArgs() const { + ArrayRef getElementMapping() const { return {getTrailingObjects(), - static_cast(Bits.TupleShuffleExpr.NumVariadicArgs)}; - } - - /// Retrieve the owner of the default arguments. - ConcreteDeclRef getDefaultArgsOwner() const { return DefaultArgsOwner; } - - /// Retrieve the caller-defaulted arguments. - ArrayRef getCallerDefaultArgs() const { - return {getTrailingObjects(), - static_cast(Bits.TupleShuffleExpr.NumCallerDefaultArgs)}; - } - - /// Retrieve the caller-defaulted arguments. - MutableArrayRef getCallerDefaultArgs() { - return {getTrailingObjects(), - static_cast(Bits.TupleShuffleExpr.NumCallerDefaultArgs)}; + static_cast(Bits.TupleShuffleExpr.NumElementMappings)}; } static bool classof(const Expr *E) { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 5f30d467909b3..d80031691ea5d 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -2119,37 +2119,12 @@ class PrintExpr : public ExprVisitor { } void visitTupleShuffleExpr(TupleShuffleExpr *E) { printCommon(E, "tuple_shuffle_expr"); - switch (E->getTypeImpact()) { - case TupleShuffleExpr::ScalarToTuple: - OS << " scalar_to_tuple"; - break; - case TupleShuffleExpr::TupleToTuple: - OS << " tuple_to_tuple"; - break; - case TupleShuffleExpr::TupleToScalar: - OS << " tuple_to_scalar"; - break; - } OS << " elements=["; for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) { if (i) OS << ", "; OS << E->getElementMapping()[i]; } - OS << "]"; - OS << " variadic_sources=["; - interleave(E->getVariadicArgs(), - [&](unsigned source) { - OS << source; - }, - [&] { OS << ", "; }); - OS << "]"; - - if (auto defaultArgsOwner = E->getDefaultArgsOwner()) { - OS << " default_args_owner="; - defaultArgsOwner.dump(OS); - } - - OS << "\n"; + OS << "]\n"; printRec(E->getSubExpr()); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index e2fd9f372288a..a285ce696c186 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -1992,57 +1992,22 @@ class Verifier : public ASTWalker { PrettyStackTraceExpr debugStack(Ctx, "verifying TupleShuffleExpr", E); auto getSubElementType = [&](unsigned i) { - if (E->isSourceScalar()) { - assert(i == 0); - return E->getSubExpr()->getType(); - } else { - return (E->getSubExpr()->getType()->castTo() - ->getElementType(i)); - } + return (E->getSubExpr()->getType()->castTo() + ->getElementType(i)); }; /// Retrieve the ith element type from the resulting tuple type. auto getOuterElementType = [&](unsigned i) -> Type { - if (E->isResultScalar()) { - assert(i == 0); - return E->getType()->getWithoutParens(); - } else { - return E->getType()->castTo()->getElementType(i); - } + return E->getType()->castTo()->getElementType(i); }; - Type varargsType; - unsigned callerDefaultArgIndex = 0; for (unsigned i = 0, e = E->getElementMapping().size(); i != e; ++i) { int subElem = E->getElementMapping()[i]; - if (subElem == TupleShuffleExpr::DefaultInitialize) - continue; - if (subElem == TupleShuffleExpr::Variadic) { - varargsType = (E->getType()->castTo() - ->getElement(i).getVarargBaseTy()); - break; - } - if (subElem == TupleShuffleExpr::CallerDefaultInitialize) { - auto init = E->getCallerDefaultArgs()[callerDefaultArgIndex++]; - if (!getOuterElementType(i)->isEqual(init->getType())) { - Out << "Type mismatch in TupleShuffleExpr\n"; - abort(); - } - continue; - } if (!getOuterElementType(i)->isEqual(getSubElementType(subElem))) { Out << "Type mismatch in TupleShuffleExpr\n"; abort(); } } - if (varargsType) { - for (auto sourceIdx : E->getVariadicArgs()) { - if (!getSubElementType(sourceIdx)->isEqual(varargsType)) { - Out << "Vararg type mismatch in TupleShuffleExpr\n"; - abort(); - } - } - } verifyCheckedBase(E); } diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index e6bfcdee1366d..82a020d62ddb2 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -646,13 +646,6 @@ class Traversal : public ASTVisitorgetCallerDefaultArgs()) { - if (Expr *newDefaultArg = doIt(defaultArg)) - defaultArg = newDefaultArg; - else - return nullptr; - } - return E; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index ecb15a46b37d5..17f9082915ecd 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1335,20 +1335,11 @@ CaptureListExpr *CaptureListExpr::create(ASTContext &ctx, TupleShuffleExpr *TupleShuffleExpr::create(ASTContext &ctx, Expr *subExpr, - ArrayRef elementMapping, - TypeImpact typeImpact, - ConcreteDeclRef defaultArgsOwner, - ArrayRef VariadicArgs, - Type VarargsArrayTy, - ArrayRef CallerDefaultArgs, + ArrayRef elementMapping, Type ty) { - auto size = totalSizeToAlloc(CallerDefaultArgs.size(), - elementMapping.size(), - VariadicArgs.size()); + auto size = totalSizeToAlloc(elementMapping.size()); auto mem = ctx.Allocate(size, alignof(TupleShuffleExpr)); - return ::new(mem) TupleShuffleExpr(subExpr, elementMapping, typeImpact, - defaultArgsOwner, VariadicArgs, - VarargsArrayTy, CallerDefaultArgs, ty); + return ::new(mem) TupleShuffleExpr(subExpr, elementMapping, ty); } ArgumentShuffleExpr *ArgumentShuffleExpr::create(ASTContext &ctx, diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 406ed3d4920e3..48fc0f6358ba6 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2289,19 +2289,14 @@ static void emitTupleShuffleExprInto(RValueEmitter &emitter, // Map outer initializations into a tuple of inner initializations: // - fill out the initialization elements with null TupleInitialization innerTupleInit; - if (E->isSourceScalar()) { - innerTupleInit.SubInitializations.push_back(nullptr); - } else { - CanTupleType innerTuple = - cast(E->getSubExpr()->getType()->getCanonicalType()); - innerTupleInit.SubInitializations.resize(innerTuple->getNumElements()); - } + + CanTupleType innerTuple = + cast(E->getSubExpr()->getType()->getCanonicalType()); + innerTupleInit.SubInitializations.resize(innerTuple->getNumElements()); // Map all the outer initializations to their appropriate targets. for (unsigned outerIndex = 0; outerIndex != outerInits.size(); outerIndex++) { auto innerMapping = E->getElementMapping()[outerIndex]; - assert(innerMapping >= 0 && - "non-argument tuple shuffle with default arguments or variadics?"); innerTupleInit.SubInitializations[innerMapping] = std::move(outerInits[outerIndex]); } @@ -2313,22 +2308,13 @@ static void emitTupleShuffleExprInto(RValueEmitter &emitter, #endif // Emit the sub-expression into the tuple initialization we just built. - if (E->isSourceScalar()) { - emitter.SGF.emitExprInto(E->getSubExpr(), - innerTupleInit.SubInitializations[0].get()); - } else { - emitter.SGF.emitExprInto(E->getSubExpr(), &innerTupleInit); - } + emitter.SGF.emitExprInto(E->getSubExpr(), &innerTupleInit); outerTupleInit->finishInitialization(emitter.SGF); } RValue RValueEmitter::visitTupleShuffleExpr(TupleShuffleExpr *E, SGFContext C) { - // FIXME: Once we're no longer using this code path for enum element payloads, - // also assert that !E->isSourceScalar(). - assert(!E->isResultScalar()); - // If we're emitting into an initialization, we can try shuffling the // elements of the initialization. if (Initialization *I = C.getEmitInto()) { @@ -2340,12 +2326,8 @@ RValue RValueEmitter::visitTupleShuffleExpr(TupleShuffleExpr *E, // Emit the sub-expression tuple and destructure it into elements. SmallVector elements; - if (E->isSourceScalar()) { - elements.push_back(visit(E->getSubExpr())); - } else { - visit(E->getSubExpr()).extractElements(elements); - } - + visit(E->getSubExpr()).extractElements(elements); + // Prepare a new tuple to hold the shuffled result. RValue result(E->getType()->getCanonicalType()); @@ -2359,11 +2341,6 @@ RValue RValueEmitter::visitTupleShuffleExpr(TupleShuffleExpr *E, "ran out of shuffle indexes before running out of fields?!"); int shuffleIndex = *shuffleIndexIterator++; - assert(shuffleIndex != TupleShuffleExpr::DefaultInitialize && - shuffleIndex != TupleShuffleExpr::CallerDefaultInitialize && - shuffleIndex != TupleShuffleExpr::Variadic && - "Only argument tuples can have default initializers & varargs"); - // Map from a different tuple element. result.addElement( std::move(elements[shuffleIndex]).ensurePlusOne(SGF, E)); diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 182dfcc63ef66..4200a6fbe472b 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -5108,23 +5108,10 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple, return expr; } - // computeTupleShuffle() produces an array of unsigned (since it can only - // contain tuple element indices). However TupleShuffleExpr is also used - // for call argument lists which can contain special things like default - // arguments and variadics; those are presented by negative integers. - // - // FIXME: Design and implement a new AST where argument lists are - // separate from rvalue tuple conversions. - ArrayRef sourcesRef = sources; - ArrayRef sourcesCast((const int *) sourcesRef.data(), - sourcesRef.size()); - // Create the tuple shuffle. return cs.cacheType(TupleShuffleExpr::create(tc.Context, - expr, sourcesCast, - TupleShuffleExpr::TupleToTuple, - ConcreteDeclRef(), {}, Type(), {}, + expr, sources, toSugarType)); }