Skip to content

Commit 8bd4100

Browse files
authored
Merge pull request #60263 from hamishknight/2-toil-2-tuple
2 parents 1b30a64 + 9da5319 commit 8bd4100

33 files changed

+176
-342
lines changed

include/swift/AST/TypeMatcher.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@ class TypeMatcher {
125125
const auto &firstElt = firstTuple->getElements()[i];
126126
const auto &secondElt = secondTuple->getElements()[i];
127127

128-
if (firstElt.getName() != secondElt.getName() ||
129-
firstElt.isVararg() != secondElt.isVararg())
128+
if (firstElt.getName() != secondElt.getName()) {
130129
return mismatch(firstTuple.getPointer(), secondTuple,
131130
sugaredFirstType);
131+
}
132132

133133
// Recurse on the tuple elements.
134134
if (!this->visit(firstTuple.getElementType(i), secondElt.getType(),

include/swift/AST/Types.h

Lines changed: 43 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
363363
HasCachedType : 1
364364
);
365365

366-
enum { NumFlagBits = 8 };
367-
SWIFT_INLINE_BITFIELD(ParenType, SugarType, NumFlagBits,
368-
/// Whether there is an original type.
369-
Flags : NumFlagBits
370-
);
366+
SWIFT_INLINE_BITFIELD_EMPTY(ParenType, SugarType);
371367

372368
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+1+1+16,
373369
/// Extra information which affects how the function is called, like
@@ -429,11 +425,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
429425
ArgCount : 32
430426
);
431427

432-
SWIFT_INLINE_BITFIELD_FULL(TupleType, TypeBase, 1+32,
433-
/// Whether an element of the tuple is inout, __shared or __owned.
434-
/// Values cannot have such tuple types in the language.
435-
HasElementWithOwnership : 1,
436-
428+
SWIFT_INLINE_BITFIELD_FULL(TupleType, TypeBase, 32,
437429
: NumPadBits,
438430

439431
/// The number of elements of the tuple.
@@ -724,8 +716,8 @@ class alignas(1 << TypeAlignInBits) TypeBase
724716
return getRecursiveProperties().isLValue();
725717
}
726718

727-
/// Is this a first-class value type, meaning it is not an InOutType or a
728-
/// tuple type containing an InOutType?
719+
/// Is this a first-class value type, meaning it is not an LValueType or an
720+
/// InOutType.
729721
bool isMaterializable();
730722

731723
/// Is this a non-escaping type, that is, a non-escaping function type or a
@@ -1995,11 +1987,6 @@ class TypeAliasType final
19951987
}
19961988
};
19971989

1998-
// TODO: As part of AST modernization, replace with a proper
1999-
// 'ParameterTypeElt' or similar, and have FunctionTypes only have a list
2000-
// of 'ParameterTypeElt's. Then, this information can be removed from
2001-
// TupleTypeElt.
2002-
//
20031990
/// Provide parameter type relevant flags, i.e. variadic, autoclosure, and
20041991
/// escaping.
20051992
class ParameterTypeFlags {
@@ -2123,6 +2110,28 @@ class ParameterTypeFlags {
21232110
uint16_t toRaw() const { return value.toRaw(); }
21242111
};
21252112

2113+
/// A type that indicates how parameter flags should be handled in an operation
2114+
/// that requires the conversion into a type that doesn't support them, such as
2115+
/// tuples.
2116+
enum class ParameterFlagHandling {
2117+
/// Ignores any parameter flags that may be present, dropping them from the
2118+
/// result. This should only be used in specific cases, including e.g:
2119+
///
2120+
/// - The flags have already been handled, and unsuitable flags have been
2121+
/// rejected or asserted to not be present.
2122+
/// - The flags aren't relevant for the particular conversion (e.g for type
2123+
/// printing or compatibility logic).
2124+
/// - The conversion is only interested in the 'internal argument' of a
2125+
/// parameter, in which case only the type and label are relevant.
2126+
///
2127+
/// In all other cases, you ought to verify that unsuitable flags are not
2128+
/// present, or add assertions to that effect.
2129+
IgnoreNonEmpty,
2130+
2131+
/// Asserts that no parameter flags are present.
2132+
AssertEmpty
2133+
};
2134+
21262135
class YieldTypeFlags {
21272136
enum YieldFlags : uint8_t {
21282137
None = 0,
@@ -2196,21 +2205,12 @@ class YieldTypeFlags {
21962205

21972206
/// ParenType - A paren type is a type that's been written in parentheses.
21982207
class ParenType : public SugarType {
2199-
friend class ASTContext;
2200-
2201-
ParenType(Type UnderlyingType, RecursiveTypeProperties properties,
2202-
ParameterTypeFlags flags);
2208+
ParenType(Type UnderlyingType, RecursiveTypeProperties properties);
22032209

22042210
public:
2205-
Type getUnderlyingType() const { return getSinglyDesugaredType(); }
2206-
2207-
static ParenType *get(const ASTContext &C, Type underlying,
2208-
ParameterTypeFlags flags = {});
2211+
static ParenType *get(const ASTContext &C, Type underlying);
22092212

2210-
/// Get the parameter flags
2211-
ParameterTypeFlags getParameterFlags() const {
2212-
return ParameterTypeFlags::fromRaw(Bits.ParenType.Flags);
2213-
}
2213+
Type getUnderlyingType() const { return getSinglyDesugaredType(); }
22142214

22152215
// Implement isa/cast/dyncast/etc.
22162216
static bool classof(const TypeBase *T) {
@@ -2226,37 +2226,17 @@ class TupleTypeElt {
22262226
/// This is the type of the field.
22272227
Type ElementType;
22282228

2229-
/// Flags that are specific to and relevant for parameter types
2230-
ParameterTypeFlags Flags;
2231-
22322229
friend class TupleType;
22332230

22342231
public:
22352232
TupleTypeElt() = default;
2236-
TupleTypeElt(Type ty, Identifier name = Identifier(),
2237-
ParameterTypeFlags fl = {});
2238-
2233+
TupleTypeElt(Type ty, Identifier name = Identifier());
2234+
22392235
bool hasName() const { return !Name.empty(); }
22402236
Identifier getName() const { return Name; }
2241-
2242-
Type getRawType() const { return ElementType; }
2243-
Type getType() const;
22442237

2245-
ParameterTypeFlags getParameterFlags() const { return Flags; }
2238+
Type getType() const { return ElementType; }
22462239

2247-
/// Determine whether this field is variadic.
2248-
bool isVararg() const { return Flags.isVariadic(); }
2249-
2250-
/// Determine whether this field is an autoclosure parameter closure.
2251-
bool isAutoClosure() const { return Flags.isAutoClosure(); }
2252-
2253-
/// Determine whether this field is marked 'inout'.
2254-
bool isInOut() const { return Flags.isInOut(); }
2255-
2256-
/// Remove the type of this varargs element designator, without the array
2257-
/// type wrapping it.
2258-
Type getVarargBaseTy() const;
2259-
22602240
/// Retrieve a copy of this tuple type element with the type replaced.
22612241
TupleTypeElt getWithType(Type T) const;
22622242

@@ -2318,11 +2298,6 @@ class TupleType final : public TypeBase, public llvm::FoldingSetNode,
23182298
/// getNamedElementId - If this tuple has an element with the specified name,
23192299
/// return the element index, otherwise return -1.
23202300
int getNamedElementId(Identifier I) const;
2321-
2322-
/// Returns true if this tuple has inout, __shared or __owned elements.
2323-
bool hasElementWithOwnership() const {
2324-
return static_cast<bool>(Bits.TupleType.HasElementWithOwnership);
2325-
}
23262301

23272302
// Implement isa/cast/dyncast/etc.
23282303
static bool classof(const TypeBase *T) {
@@ -2337,13 +2312,11 @@ class TupleType final : public TypeBase, public llvm::FoldingSetNode,
23372312

23382313
private:
23392314
TupleType(ArrayRef<TupleTypeElt> elements, const ASTContext *CanCtx,
2340-
RecursiveTypeProperties properties,
2341-
bool hasElementWithOwnership)
2342-
: TypeBase(TypeKind::Tuple, CanCtx, properties) {
2343-
Bits.TupleType.HasElementWithOwnership = hasElementWithOwnership;
2344-
Bits.TupleType.Count = elements.size();
2345-
std::uninitialized_copy(elements.begin(), elements.end(),
2346-
getTrailingObjects<TupleTypeElt>());
2315+
RecursiveTypeProperties properties)
2316+
: TypeBase(TypeKind::Tuple, CanCtx, properties) {
2317+
Bits.TupleType.Count = elements.size();
2318+
std::uninitialized_copy(elements.begin(), elements.end(),
2319+
getTrailingObjects<TupleTypeElt>());
23472320
}
23482321
};
23492322
BEGIN_CAN_TYPE_WRAPPER(TupleType, Type)
@@ -3127,10 +3100,9 @@ class AnyFunctionType : public TypeBase {
31273100
public:
31283101
/// Take an array of parameters and turn it into a tuple or paren type.
31293102
///
3130-
/// \param wantParamFlags Whether to preserve the parameter flags from the
3131-
/// given set of parameters.
3103+
/// \param paramFlagHandling How to handle the parameter flags.
31323104
static Type composeTuple(ASTContext &ctx, ArrayRef<Param> params,
3133-
bool wantParamFlags = true);
3105+
ParameterFlagHandling paramFlagHandling);
31343106

31353107
/// Given two arrays of parameters determine if they are equal in their
31363108
/// canonicalized form. Internal labels and type sugar is *not* taken into
@@ -6533,17 +6505,9 @@ inline bool TypeBase::isTypeSequenceParameter() {
65336505
t->castTo<GenericTypeParamType>()->isTypeSequence();
65346506
}
65356507

6508+
// TODO: This will become redundant once InOutType is removed.
65366509
inline bool TypeBase::isMaterializable() {
6537-
if (hasLValueType())
6538-
return false;
6539-
6540-
if (is<InOutType>())
6541-
return false;
6542-
6543-
if (auto *TTy = getAs<TupleType>())
6544-
return !TTy->hasElementWithOwnership();
6545-
6546-
return true;
6510+
return !(hasLValueType() || is<InOutType>());
65476511
}
65486512

65496513
inline GenericTypeParamType *TypeBase::getRootGenericParam() {
@@ -6755,26 +6719,12 @@ inline bool CanType::isActuallyCanonicalOrNull() const {
67556719
getPointer()->isCanonical();
67566720
}
67576721

6758-
inline Type TupleTypeElt::getVarargBaseTy() const {
6759-
TypeBase *T = getType().getPointer();
6760-
if (auto *AT = dyn_cast<VariadicSequenceType>(T))
6761-
return AT->getBaseType();
6762-
if (auto *BGT = dyn_cast<BoundGenericType>(T)) {
6763-
// It's the stdlib Array<T>.
6764-
return BGT->getGenericArgs()[0];
6765-
}
6766-
assert(T->hasError());
6767-
return T;
6768-
}
6769-
67706722
inline TupleTypeElt TupleTypeElt::getWithName(Identifier name) const {
6771-
assert(getParameterFlags().isInOut() == getType()->is<InOutType>());
6772-
return TupleTypeElt(getRawType(), name, getParameterFlags());
6723+
return TupleTypeElt(getType(), name);
67736724
}
67746725

67756726
inline TupleTypeElt TupleTypeElt::getWithType(Type T) const {
6776-
auto flags = getParameterFlags().withInOut(T->is<InOutType>());
6777-
return TupleTypeElt(T->getInOutObjectType(), getName(), flags);
6727+
return TupleTypeElt(T, getName());
67786728
}
67796729

67806730
/// Create one from what's present in the parameter decl and type

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,9 @@ SwiftDeclCollector::constructTypeNode(Type T, TypeInitInfo Info) {
16011601
// Still, return type first
16021602
Root->addChild(constructTypeNode(Fun->getResult()));
16031603

1604-
auto Input = AnyFunctionType::composeTuple(Fun->getASTContext(),
1605-
Fun->getParams());
1604+
auto Input =
1605+
AnyFunctionType::composeTuple(Fun->getASTContext(), Fun->getParams(),
1606+
ParameterFlagHandling::IgnoreNonEmpty);
16061607
Root->addChild(constructTypeNode(Input));
16071608
return Root;
16081609
}

lib/AST/ASTContext.cpp

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,7 @@ struct ASTContext::Implementation {
397397
llvm::DenseMap<Type, VariadicSequenceType*> VariadicSequenceTypes;
398398
llvm::DenseMap<std::pair<Type, Type>, DictionaryType *> DictionaryTypes;
399399
llvm::DenseMap<Type, OptionalType*> OptionalTypes;
400-
llvm::DenseMap<Type, ParenType*> SimpleParenTypes; // Most are simple
401-
llvm::DenseMap<std::pair<Type, unsigned>, ParenType*> ParenTypes;
400+
llvm::DenseMap<Type, ParenType*> ParenTypes;
402401
llvm::DenseMap<uintptr_t, ReferenceStorageType*> ReferenceStorageTypes;
403402
llvm::DenseMap<Type, LValueType*> LValueTypes;
404403
llvm::DenseMap<Type, InOutType*> InOutTypes;
@@ -2626,7 +2625,6 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
26262625
llvm::capacity_in_bytes(DictionaryTypes) +
26272626
llvm::capacity_in_bytes(OptionalTypes) +
26282627
llvm::capacity_in_bytes(VariadicSequenceTypes) +
2629-
llvm::capacity_in_bytes(SimpleParenTypes) +
26302628
llvm::capacity_in_bytes(ParenTypes) +
26312629
llvm::capacity_in_bytes(ReferenceStorageTypes) +
26322630
llvm::capacity_in_bytes(LValueTypes) +
@@ -2836,22 +2834,14 @@ BuiltinVectorType *BuiltinVectorType::get(const ASTContext &context,
28362834
return vecTy;
28372835
}
28382836

2839-
ParenType *ParenType::get(const ASTContext &C, Type underlying,
2840-
ParameterTypeFlags fl) {
2841-
if (fl.isInOut())
2842-
assert(!underlying->is<InOutType>() && "caller did not pass a base type");
2843-
if (underlying->is<InOutType>())
2844-
assert(fl.isInOut() && "caller did not set flags correctly");
2845-
2837+
ParenType *ParenType::get(const ASTContext &C, Type underlying) {
28462838
auto properties = underlying->getRecursiveProperties();
28472839
auto arena = getArena(properties);
2848-
auto flags = fl.toRaw();
2849-
ParenType *&Result = flags == 0
2850-
? C.getImpl().getArena(arena).SimpleParenTypes[underlying]
2851-
: C.getImpl().getArena(arena).ParenTypes[{underlying, flags}];
2840+
ParenType *&Result = C.getImpl().getArena(arena).ParenTypes[underlying];
28522841
if (Result == nullptr) {
2853-
Result = new (C, arena) ParenType(underlying,
2854-
properties, fl);
2842+
Result = new (C, arena) ParenType(underlying, properties);
2843+
assert((C.hadError() || !underlying->is<InOutType>()) &&
2844+
"Cannot wrap InOutType");
28552845
}
28562846
return Result;
28572847
}
@@ -2866,35 +2856,19 @@ void TupleType::Profile(llvm::FoldingSetNodeID &ID,
28662856
for (const TupleTypeElt &Elt : Fields) {
28672857
ID.AddPointer(Elt.Name.get());
28682858
ID.AddPointer(Elt.getType().getPointer());
2869-
ID.AddInteger(Elt.Flags.toRaw());
28702859
}
28712860
}
28722861

28732862
/// getTupleType - Return the uniqued tuple type with the specified elements.
28742863
Type TupleType::get(ArrayRef<TupleTypeElt> Fields, const ASTContext &C) {
2875-
if (Fields.size() == 1 && !Fields[0].isVararg() && !Fields[0].hasName())
2876-
return ParenType::get(C, Fields[0].getRawType(),
2877-
Fields[0].getParameterFlags());
2864+
if (Fields.size() == 1 && !Fields[0].hasName())
2865+
return ParenType::get(C, Fields[0].getType());
28782866

28792867
RecursiveTypeProperties properties;
2880-
bool hasElementWithOwnership = false;
28812868
for (const TupleTypeElt &Elt : Fields) {
28822869
auto eltTy = Elt.getType();
28832870
if (!eltTy) continue;
2884-
28852871
properties |= eltTy->getRecursiveProperties();
2886-
// Recur into paren types and canonicalized paren types. 'inout' in nested
2887-
// non-paren tuples are malformed and will be diagnosed later.
2888-
if (auto *TTy = Elt.getType()->getAs<TupleType>()) {
2889-
if (TTy->getNumElements() == 1)
2890-
hasElementWithOwnership |= TTy->hasElementWithOwnership();
2891-
} else if (auto *Pty = dyn_cast<ParenType>(Elt.getType().getPointer())) {
2892-
hasElementWithOwnership |= (Pty->getParameterFlags().getValueOwnership() !=
2893-
ValueOwnership::Default);
2894-
} else {
2895-
hasElementWithOwnership |= (Elt.getParameterFlags().getValueOwnership() !=
2896-
ValueOwnership::Default);
2897-
}
28982872
}
28992873

29002874
auto arena = getArena(properties);
@@ -2919,24 +2893,15 @@ Type TupleType::get(ArrayRef<TupleTypeElt> Fields, const ASTContext &C) {
29192893
size_t bytes = totalSizeToAlloc<TupleTypeElt>(Fields.size());
29202894
// TupleType will copy the fields list into ASTContext owned memory.
29212895
void *mem = C.Allocate(bytes, alignof(TupleType), arena);
2922-
auto New = new (mem) TupleType(Fields, IsCanonical ? &C : nullptr, properties,
2923-
hasElementWithOwnership);
2896+
auto New = new (mem) TupleType(Fields, IsCanonical ? &C : nullptr,
2897+
properties);
29242898
C.getImpl().getArena(arena).TupleTypes.InsertNode(New, InsertPos);
29252899
return New;
29262900
}
29272901

2928-
TupleTypeElt::TupleTypeElt(Type ty, Identifier name,
2929-
ParameterTypeFlags fl)
2930-
: Name(name), ElementType(ty), Flags(fl) {
2931-
if (fl.isInOut())
2932-
assert(!ty->is<InOutType>() && "caller did not pass a base type");
2933-
if (ty->is<InOutType>())
2934-
assert(fl.isInOut() && "caller did not set flags correctly");
2935-
}
2936-
2937-
Type TupleTypeElt::getType() const {
2938-
if (Flags.isInOut()) return InOutType::get(ElementType);
2939-
return ElementType;
2902+
TupleTypeElt::TupleTypeElt(Type ty, Identifier name)
2903+
: Name(name), ElementType(ty) {
2904+
assert(!ty->is<InOutType>() && "Cannot have InOutType in a tuple");
29402905
}
29412906

29422907
PackExpansionType *PackExpansionType::get(Type patternTy) {
@@ -3623,12 +3588,17 @@ Type AnyFunctionType::Param::getParameterType(bool forCanonical,
36233588
}
36243589

36253590
Type AnyFunctionType::composeTuple(ASTContext &ctx, ArrayRef<Param> params,
3626-
bool wantParamFlags) {
3591+
ParameterFlagHandling paramFlagHandling) {
36273592
SmallVector<TupleTypeElt, 4> elements;
36283593
for (const auto &param : params) {
3629-
auto flags = wantParamFlags ? param.getParameterFlags()
3630-
: ParameterTypeFlags();
3631-
elements.emplace_back(param.getParameterType(), param.getLabel(), flags);
3594+
switch (paramFlagHandling) {
3595+
case ParameterFlagHandling::IgnoreNonEmpty:
3596+
break;
3597+
case ParameterFlagHandling::AssertEmpty:
3598+
assert(param.getParameterFlags().isNone());
3599+
break;
3600+
}
3601+
elements.emplace_back(param.getParameterType(), param.getLabel());
36323602
}
36333603
return TupleType::get(elements, ctx);
36343604
}

0 commit comments

Comments
 (0)