Skip to content

Commit 5714bca

Browse files
committed
[NFC] Decompose function input types
Prepares the AST for future work to eliminate `getInput()` and perform function type argument matching in a less ad-hoc manner.
1 parent db3796d commit 5714bca

File tree

3 files changed

+69
-45
lines changed

3 files changed

+69
-45
lines changed

include/swift/AST/Types.h

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,7 +2282,35 @@ getSILFunctionLanguage(SILFunctionTypeRepresentation rep) {
22822282

22832283
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch.");
22842284
}
2285-
2285+
2286+
/// A call argument or parameter.
2287+
struct CallArgParam {
2288+
/// The type of the argument or parameter. For a variadic parameter,
2289+
/// this is the element type.
2290+
Type Ty;
2291+
2292+
// The label associated with the argument or parameter, if any.
2293+
Identifier Label;
2294+
2295+
/// Whether the parameter has a default argument. Not valid for arguments.
2296+
bool HasDefaultArgument = false;
2297+
2298+
/// Parameter specific flags, not valid for arguments
2299+
ParameterTypeFlags parameterFlags = {};
2300+
2301+
/// Whether the argument or parameter has a label.
2302+
bool hasLabel() const { return !Label.empty(); }
2303+
2304+
/// Whether the parameter is varargs
2305+
bool isVariadic() const { return parameterFlags.isVariadic(); }
2306+
2307+
/// Whether the parameter is autoclosure
2308+
bool isAutoClosure() const { return parameterFlags.isAutoClosure(); }
2309+
2310+
/// Whether the parameter is escaping
2311+
bool isEscaping() const { return parameterFlags.isEscaping(); }
2312+
};
2313+
22862314
/// AnyFunctionType - A function type has a single input and result, but
22872315
/// these types may be tuples, for example:
22882316
/// "(int) -> int" or "(a : int, b : int) -> (int, int)".
@@ -2295,7 +2323,8 @@ getSILFunctionLanguage(SILFunctionTypeRepresentation rep) {
22952323
/// be 'thin', indicating that a function value has no capture context and can be
22962324
/// represented at the binary level as a single function pointer.
22972325
class AnyFunctionType : public TypeBase {
2298-
const Type Input;
2326+
const ArrayRef<CallArgParam> Input;
2327+
const Type RawInput;
22992328
const Type Output;
23002329

23012330
public:
@@ -2441,15 +2470,13 @@ class AnyFunctionType : public TypeBase {
24412470

24422471
protected:
24432472
AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext,
2444-
Type Input, Type Output, RecursiveTypeProperties properties,
2445-
const ExtInfo &Info)
2446-
: TypeBase(Kind, CanTypeContext, properties), Input(Input), Output(Output) {
2447-
AnyFunctionTypeBits.ExtInfo = Info.Bits;
2448-
}
2473+
ArrayRef<CallArgParam> Input, Type RawInput, Type Output,
2474+
RecursiveTypeProperties properties,
2475+
const ExtInfo &Info);
24492476

24502477
public:
24512478

2452-
Type getInput() const { return Input; }
2479+
Type getInput() const { return RawInput; }
24532480
Type getResult() const { return Output; }
24542481

24552482
ExtInfo getExtInfo() const {
@@ -2533,41 +2560,14 @@ BEGIN_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
25332560
return CanFunctionType(cast<FunctionType>(getPointer()->withExtInfo(info)));
25342561
}
25352562
END_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
2536-
2537-
/// A call argument or parameter.
2538-
struct CallArgParam {
2539-
/// The type of the argument or parameter. For a variadic parameter,
2540-
/// this is the element type.
2541-
Type Ty;
2542-
2543-
// The label associated with the argument or parameter, if any.
2544-
Identifier Label;
2545-
2546-
/// Whether the parameter has a default argument. Not valid for arguments.
2547-
bool HasDefaultArgument = false;
2548-
2549-
/// Parameter specific flags, not valid for arguments
2550-
ParameterTypeFlags parameterFlags = {};
2551-
2552-
/// Whether the argument or parameter has a label.
2553-
bool hasLabel() const { return !Label.empty(); }
2554-
2555-
/// Whether the parameter is varargs
2556-
bool isVariadic() const { return parameterFlags.isVariadic(); }
2557-
2558-
/// Whether the parameter is autoclosure
2559-
bool isAutoClosure() const { return parameterFlags.isAutoClosure(); }
2560-
2561-
/// Whether the parameter is escaping
2562-
bool isEscaping() const { return parameterFlags.isEscaping(); }
2563-
};
2564-
2563+
25652564
/// Break an argument type into an array of \c CallArgParams.
25662565
///
25672566
/// \param type The type to decompose.
25682567
/// \param argumentLabels The argument labels to use.
25692568
SmallVector<CallArgParam, 4>
2570-
decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels);
2569+
decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels,
2570+
bool inAnyFunctionType = false);
25712571

25722572
/// Break a parameter type into an array of \c CallArgParams.
25732573
///

lib/AST/ASTContext.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,16 @@ getGenericFunctionRecursiveProperties(Type Input, Type Result) {
31363136
return properties;
31373137
}
31383138

3139+
AnyFunctionType::AnyFunctionType(TypeKind Kind, const ASTContext *CanTypeContext,
3140+
ArrayRef<CallArgParam> Input, Type RawInput, Type Output,
3141+
RecursiveTypeProperties properties,
3142+
const ExtInfo &Info)
3143+
: TypeBase(Kind, CanTypeContext, properties),
3144+
Input((CanTypeContext ?: &RawInput->getASTContext())->AllocateCopy(Input)),
3145+
RawInput(RawInput), Output(Output) {
3146+
AnyFunctionTypeBits.ExtInfo = Info.Bits;
3147+
}
3148+
31393149
AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const {
31403150
if (isa<FunctionType>(this))
31413151
return FunctionType::get(getInput(), getResult(), info);
@@ -3167,6 +3177,17 @@ FunctionType *FunctionType::get(Type Input, Type Result,
31673177
Info);
31683178
}
31693179

3180+
static SmallVector<CallArgParam, 4> decomposeInput(Type ty) {
3181+
if (auto *TTy = dyn_cast<TupleType>(ty.getPointer())) {
3182+
SmallVector<Identifier, 4> labels;
3183+
for (auto &ttyElt : TTy->getElements()) {
3184+
labels.push_back(ttyElt.getName());
3185+
}
3186+
return decomposeArgType(TTy, labels, /*inAnyFunctionType*/true);
3187+
}
3188+
return decomposeArgType(ty, { Identifier() }, /*inAnyFunctionType*/true);
3189+
}
3190+
31703191
// If the input and result types are canonical, then so is the result.
31713192
FunctionType::FunctionType(Type input, Type output,
31723193
RecursiveTypeProperties properties,
@@ -3175,7 +3196,7 @@ FunctionType::FunctionType(Type input, Type output,
31753196
(input->isCanonical() && output->isCanonical())
31763197
? &input->getASTContext()
31773198
: nullptr,
3178-
input, output, properties, Info) {}
3199+
decomposeInput(input), input, output, properties, Info) {}
31793200

31803201
void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID,
31813202
GenericSignature *sig,
@@ -3242,8 +3263,8 @@ GenericFunctionType::GenericFunctionType(
32423263
const ExtInfo &info,
32433264
const ASTContext *ctx,
32443265
RecursiveTypeProperties properties)
3245-
: AnyFunctionType(TypeKind::GenericFunction, ctx, input, result,
3246-
properties, info),
3266+
: AnyFunctionType(TypeKind::GenericFunction, ctx, decomposeInput(input),
3267+
input, result, properties, info),
32473268
Signature(sig)
32483269
{}
32493270

lib/AST/Type.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,8 @@ Type TypeBase::replaceCovariantResultType(Type newResultType,
710710
}
711711

712712
SmallVector<CallArgParam, 4>
713-
swift::decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels) {
713+
swift::decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels,
714+
bool inAnyFunctionType) {
714715
SmallVector<CallArgParam, 4> result;
715716
switch (type->getKind()) {
716717
case TypeKind::Tuple: {
@@ -727,9 +728,11 @@ swift::decomposeArgType(Type type, ArrayRef<Identifier> argumentLabels) {
727728

728729
for (auto i : range(0, tupleTy->getNumElements())) {
729730
const auto &elt = tupleTy->getElement(i);
730-
assert(elt.getParameterFlags().isNone() &&
731-
"Vararg, autoclosure, or escaping argument tuple"
732-
"doesn't make sense");
731+
if (!inAnyFunctionType) {
732+
assert(elt.getParameterFlags().isNone() &&
733+
"Vararg, autoclosure, or escaping argument tuple"
734+
"doesn't make sense");
735+
}
733736
CallArgParam argParam;
734737
argParam.Ty = elt.getType();
735738
argParam.Label = argumentLabels[i];

0 commit comments

Comments
 (0)