Skip to content

Commit db63557

Browse files
authored
Merge pull request #18651 from slavapestov/avoid-building-tuple-types
New way of directly building FunctionType::Params from ParameterLists
2 parents cd4909b + f44ff38 commit db63557

File tree

9 files changed

+117
-166
lines changed

9 files changed

+117
-166
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4729,10 +4729,6 @@ class ParamDecl : public VarDecl {
47294729
/// was specified separately from the parameter name.
47304730
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }
47314731

4732-
/// Retrieve the parameter type flags corresponding to the declaration of
4733-
/// this parameter's argument type.
4734-
ParameterTypeFlags getParameterFlags() const;
4735-
47364732
SourceLoc getSpecifierLoc() const { return SpecifierLoc; }
47374733

47384734
bool isTypeLocImplicit() const { return Bits.ParamDecl.IsTypeLocImplicit; }
@@ -5772,8 +5768,8 @@ class EnumElementDecl : public ValueDecl {
57725768
}
57735769

57745770
/// Set the interface type of this enum element to the constructor function
5775-
/// type; (Self) -> Result or (Self) -> (Args...) -> Result.
5776-
bool computeType();
5771+
/// type; (Self.Type) -> Self or (Self.Type) -> (Args...) -> Self.
5772+
void computeType();
57775773

57785774
Type getArgumentInterfaceType() const;
57795775

include/swift/AST/ParameterList.h

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,23 +123,14 @@ class alignas(ParamDecl *) ParameterList final :
123123
ParameterList *clone(const ASTContext &C,
124124
OptionSet<CloneFlags> options = None) const;
125125

126-
/// Return a TupleType or ParenType for this parameter list,
127-
/// based on types provided by a callback.
128-
Type getType(const ASTContext &C,
129-
llvm::function_ref<Type(ParamDecl *)> getType) const;
130-
131-
/// Return a TupleType or ParenType for this parameter list, written in terms
132-
/// of contextual archetypes.
133-
Type getType(const ASTContext &C) const;
126+
/// Return a list of function parameters for this parameter list,
127+
/// based on the interface types of the parameters in this list.
128+
void getParams(SmallVectorImpl<AnyFunctionType::Param> &params) const;
134129

135-
/// Return a TupleType or ParenType for this parameter list, written in terms
136-
/// of interface types.
137-
Type getInterfaceType(const ASTContext &C) const;
138-
139-
/// Return the full function type for a set of curried parameter lists that
140-
/// returns the specified result type written in terms of interface types.
141-
static Type getFullInterfaceType(Type resultType, ArrayRef<ParameterList*> PL,
142-
const ASTContext &C);
130+
/// Return a list of function parameters for this parameter list,
131+
/// based on types provided by a callback.
132+
void getParams(SmallVectorImpl<AnyFunctionType::Param> &params,
133+
llvm::function_ref<Type(ParamDecl *)> getType) const;
143134

144135

145136
/// Return the full source range of this parameter.

lib/AST/Decl.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4799,11 +4799,6 @@ ParamDecl *ParamDecl::createSelf(SourceLoc loc, DeclContext *DC,
47994799
return selfDecl;
48004800
}
48014801

4802-
ParameterTypeFlags ParamDecl::getParameterFlags() const {
4803-
return ParameterTypeFlags::fromParameterType(getType(), isVariadic(),
4804-
getValueOwnership());
4805-
}
4806-
48074802
/// Return the full source range of this parameter.
48084803
SourceRange ParamDecl::getSourceRange() const {
48094804
SourceLoc APINameLoc = getArgumentNameLoc();
@@ -4969,17 +4964,18 @@ Type SubscriptDecl::getElementInterfaceType() const {
49694964
}
49704965

49714966
void SubscriptDecl::computeType() {
4972-
auto &ctx = getASTContext();
4973-
49744967
auto elementTy = getElementTypeLoc().getType();
4975-
auto indicesTy = getIndices()->getInterfaceType(ctx);
4976-
Type funcTy;
49774968

4969+
SmallVector<AnyFunctionType::Param, 2> argTy;
4970+
getIndices()->getParams(argTy);
4971+
4972+
Type funcTy;
49784973
if (auto *sig = getGenericSignature())
4979-
funcTy = GenericFunctionType::get(sig, indicesTy, elementTy,
4974+
funcTy = GenericFunctionType::get(sig, argTy, elementTy,
49804975
AnyFunctionType::ExtInfo());
49814976
else
4982-
funcTy = FunctionType::get(indicesTy, elementTy);
4977+
funcTy = FunctionType::get(argTy, elementTy,
4978+
AnyFunctionType::ExtInfo());
49834979

49844980
// Record the interface type.
49854981
setInterfaceType(funcTy);
@@ -5403,8 +5399,7 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
54035399

54045400
{
54055401
SmallVector<AnyFunctionType::Param, 4> argTy;
5406-
AnyFunctionType::decomposeInput(
5407-
getParameters()->getInterfaceType(ctx), argTy);
5402+
getParameters()->getParams(argTy);
54085403

54095404
// 'throws' only applies to the innermost function.
54105405
info = info.withThrows(hasThrows());
@@ -5724,30 +5719,38 @@ SourceRange EnumElementDecl::getSourceRange() const {
57245719
return {getStartLoc(), getNameLoc()};
57255720
}
57265721

5727-
bool EnumElementDecl::computeType() {
5722+
void EnumElementDecl::computeType() {
57285723
assert(!hasInterfaceType());
57295724

5730-
EnumDecl *ED = getParentEnum();
5731-
Type resultTy = ED->getDeclaredInterfaceType();
5725+
auto &ctx = getASTContext();
5726+
auto *ED = getParentEnum();
5727+
5728+
// The type of the enum element is either (Self.Type) -> Self
5729+
// or (Self.Type) -> (Args...) -> Self.
5730+
auto resultTy = ED->getDeclaredInterfaceType();
57325731

5733-
Type selfTy = MetatypeType::get(resultTy);
5732+
SmallVector<AnyFunctionType::Param, 1> selfTy;
5733+
selfTy.emplace_back(MetatypeType::get(resultTy, ctx),
5734+
Identifier(),
5735+
ParameterTypeFlags());
57345736

5735-
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
57365737
if (auto *PL = getParameterList()) {
5737-
auto paramTy = PL->getInterfaceType(getASTContext());
5738-
resultTy = FunctionType::get(paramTy, resultTy);
5738+
SmallVector<AnyFunctionType::Param, 4> argTy;
5739+
PL->getParams(argTy);
5740+
5741+
resultTy = FunctionType::get(argTy, resultTy,
5742+
AnyFunctionType::ExtInfo());
57395743
}
57405744

5741-
if (auto *genericSig = ED->getGenericSignatureOfContext())
5745+
if (auto *genericSig = ED->getGenericSignature())
57425746
resultTy = GenericFunctionType::get(genericSig, selfTy, resultTy,
57435747
AnyFunctionType::ExtInfo());
57445748
else
5745-
resultTy = FunctionType::get(selfTy, resultTy);
5749+
resultTy = FunctionType::get(selfTy, resultTy,
5750+
AnyFunctionType::ExtInfo());
57465751

57475752
// Record the interface type.
57485753
setInterfaceType(resultTy);
5749-
5750-
return true;
57515754
}
57525755

57535756
Type EnumElementDecl::getArgumentInterfaceType() const {

lib/AST/Parameter.cpp

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -87,56 +87,29 @@ ParameterList *ParameterList::clone(const ASTContext &C,
8787
return create(C, params);
8888
}
8989

90-
/// Return a TupleType or ParenType for this parameter list,
91-
/// based on types provided by a callback.
92-
Type ParameterList::getType(
93-
const ASTContext &C, llvm::function_ref<Type(ParamDecl *)> getType) const {
94-
if (size() == 0)
95-
return TupleType::getEmpty(C);
90+
void ParameterList::getParams(
91+
SmallVectorImpl<AnyFunctionType::Param> &params) const {
92+
getParams(params,
93+
[](ParamDecl *decl) { return decl->getInterfaceType(); });
94+
}
9695

97-
SmallVector<TupleTypeElt, 8> argumentInfo;
96+
void ParameterList::getParams(
97+
SmallVectorImpl<AnyFunctionType::Param> &params,
98+
llvm::function_ref<Type(ParamDecl *)> getType) const {
99+
if (size() == 0)
100+
return;
98101

99102
for (auto P : *this) {
100103
auto type = getType(P);
101-
argumentInfo.emplace_back(
102-
type->getInOutObjectType(), P->getArgumentName(),
103-
ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
104-
P->getValueOwnership()));
105-
}
106-
107-
return TupleType::get(argumentInfo, C);
108-
}
109-
110-
/// Return a TupleType or ParenType for this parameter list, written in terms
111-
/// of contextual archetypes.
112-
Type ParameterList::getType(const ASTContext &C) const {
113-
return getType(C, [](ParamDecl *P) { return P->getType(); });
114-
}
115-
116-
/// Return a TupleType or ParenType for this parameter list, written in terms
117-
/// of interface types.
118-
Type ParameterList::getInterfaceType(const ASTContext &C) const {
119-
return getType(C, [](ParamDecl *P) {
120-
auto type = P->getInterfaceType();
121-
assert(!type->hasArchetype());
122-
return type;
123-
});
124-
}
125104

105+
if (P->isVariadic())
106+
type = ParamDecl::getVarargBaseTy(type);
126107

127-
/// Return the full function type for a set of curried parameter lists that
128-
/// returns the specified result type. This returns a null type if one of the
129-
/// ParamDecls does not have a type set for it yet.
130-
///
131-
Type ParameterList::getFullInterfaceType(Type resultType,
132-
ArrayRef<ParameterList*> PLL,
133-
const ASTContext &C) {
134-
auto result = resultType;
135-
for (auto PL : reversed(PLL)) {
136-
auto paramType = PL->getInterfaceType(C);
137-
result = FunctionType::get(paramType, result);
108+
auto label = P->getArgumentName();
109+
auto flags = ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
110+
P->getValueOwnership());
111+
params.emplace_back(type, label, flags);
138112
}
139-
return result;
140113
}
141114

142115

lib/ClangImporter/ImportDecl.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,9 +3499,7 @@ namespace {
34993499
if (!importedType)
35003500
return nullptr;
35013501

3502-
Type type = importedType.getType();
3503-
3504-
auto resultTy = type->castTo<FunctionType>()->getResult();
3502+
auto resultTy = importedType.getType();
35053503
auto loc = Impl.importSourceLoc(decl->getLocation());
35063504

35073505
if (name && name.isSimpleName()) {
@@ -3519,7 +3517,7 @@ namespace {
35193517
resultTy, /*throws*/ false,
35203518
dc, decl);
35213519

3522-
result->setInterfaceType(type);
3520+
result->computeType();
35233521
result->setValidationToChecked();
35243522
result->setIsObjC(false);
35253523
result->setIsDynamic(false);
@@ -4041,9 +4039,7 @@ namespace {
40414039

40424040
result->setAccess(getOverridableAccessLevel(dc));
40434041

4044-
auto resultTy = importedType.getType()
4045-
->castTo<FunctionType>()->getResult();
4046-
4042+
auto resultTy = importedType.getType();
40474043
auto isIUO = importedType.isImplicitlyUnwrapped();
40484044

40494045
// If the method has a related result type that is representable
@@ -6100,8 +6096,7 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
61006096
return nullptr;
61016097

61026098
// Determine the failability of this initializer.
6103-
auto oldFnType = importedType.getType()->castTo<AnyFunctionType>();
6104-
bool resultIsOptional = (bool) oldFnType->getResult()->getOptionalObjectType();
6099+
bool resultIsOptional = (bool) importedType.getType()->getOptionalObjectType();
61056100

61066101
// Update the failability appropriately based on the imported method type.
61076102
assert(resultIsOptional || !importedType.isImplicitlyUnwrapped());
@@ -6119,7 +6114,9 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
61196114

61206115
// Look for other imported constructors that occur in this context with
61216116
// the same name.
6122-
auto allocParams = oldFnType->getParams();
6117+
SmallVector<AnyFunctionType::Param, 4> allocParams;
6118+
bodyParams->getParams(allocParams);
6119+
61236120
bool ignoreNewExtensions = isa<ClassDecl>(dc);
61246121
for (auto other : ownerNominal->lookupDirect(importedName.getDeclName(),
61256122
ignoreNewExtensions)) {
@@ -6359,14 +6356,12 @@ void SwiftDeclConverter::recordObjCOverride(SubscriptDecl *subscript) {
63596356

63606357
// Compute the type of indices for our own subscript operation, lazily.
63616358
if (!unlabeledIndices) {
6362-
unlabeledIndices = subscript->getIndices()
6363-
->getInterfaceType(Impl.SwiftContext)
6359+
unlabeledIndices = subscript->getIndicesInterfaceType()
63646360
->getUnlabeledType(Impl.SwiftContext);
63656361
}
63666362

63676363
// Compute the type of indices for the subscript we found.
6368-
auto parentUnlabeledIndices = parentSub->getIndices()
6369-
->getInterfaceType(Impl.SwiftContext)
6364+
auto parentUnlabeledIndices = parentSub->getIndicesInterfaceType()
63706365
->getUnlabeledType(Impl.SwiftContext);
63716366
if (!unlabeledIndices->isEqual(parentUnlabeledIndices))
63726367
continue;

0 commit comments

Comments
 (0)