Skip to content

Commit c360c82

Browse files
committed
AST: Automatically create the 'self' parameter when needed
Parsed declarations would create an untyped 'self' parameter; synthesized, imported and deserialized declarations would get a typed one. In reality the type, if any, depends completely on the properties of the function in question, so we can just lazily create the 'self' parameter when needed. If the function already has a type, we give it a type right there; otherwise, we check if a 'self' was already created when we compute a function's type and set the type of 'self' then.
1 parent 7f2787e commit c360c82

18 files changed

+194
-364
lines changed

include/swift/AST/Decl.h

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4774,27 +4774,6 @@ class ParamDecl : public VarDecl {
47744774

47754775
SourceRange getSourceRange() const;
47764776

4777-
/// Create an implicit 'self' decl for a method in the specified decl context.
4778-
/// If 'static' is true, then this is self for a static method in the type.
4779-
///
4780-
/// Note that this decl is created, but it is returned with an incorrect
4781-
/// DeclContext that needs to be set correctly. This is automatically handled
4782-
/// when a function is created with this as part of its argument list.
4783-
/// For a generic context, this also gives the parameter an unbound generic
4784-
/// type with the expectation that type-checking will fill in the context
4785-
/// generic parameters.
4786-
static ParamDecl *createUnboundSelf(SourceLoc loc, DeclContext *DC);
4787-
4788-
/// Create an implicit 'self' decl for a method in the specified decl context.
4789-
/// If 'static' is true, then this is self for a static method in the type.
4790-
///
4791-
/// Note that this decl is created, but it is returned with an incorrect
4792-
/// DeclContext that needs to be set correctly. This is automatically handled
4793-
/// when a function is created with this as part of its argument list.
4794-
static ParamDecl *createSelf(SourceLoc loc, DeclContext *DC,
4795-
bool isStatic = false,
4796-
bool isInOut = false);
4797-
47984777
// Implement isa/cast/dyncast/etc.
47994778
static bool classof(const Decl *D) {
48004779
return D->getKind() == DeclKind::Param;
@@ -5169,6 +5148,8 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
51695148
private:
51705149
void computeNeedsNewVTableEntry();
51715150

5151+
void computeSelfDeclType();
5152+
51725153
public:
51735154
/// Compute the interface type of this function declaration from the
51745155
/// parameter types.
@@ -5202,24 +5183,21 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
52025183
return Params;
52035184
}
52045185

5205-
void setParameters(ParamDecl *SelfDecl,
5206-
ParameterList *Params);
5186+
void setParameters(ParameterList *Params);
52075187

52085188
bool hasImplicitSelfDecl() const {
52095189
return Bits.AbstractFunctionDecl.HasImplicitSelfDecl;
52105190
}
52115191

52125192
ParamDecl **getImplicitSelfDeclStorage();
52135193

5214-
/// Retrieve the implicit 'self' parameter for methods, or nullptr for free
5215-
/// functions.
5216-
const ParamDecl *getImplicitSelfDecl() const {
5217-
return const_cast<AbstractFunctionDecl*>(this)->getImplicitSelfDecl();
5218-
}
5219-
ParamDecl *getImplicitSelfDecl() {
5220-
auto **selfDecl = getImplicitSelfDeclStorage();
5221-
return (selfDecl == nullptr ? nullptr : *selfDecl);
5194+
/// Retrieve the implicit 'self' parameter for methods. Returns nullptr for
5195+
/// free functions.
5196+
const ParamDecl *getImplicitSelfDecl(bool createIfNeeded=true) const {
5197+
return const_cast<AbstractFunctionDecl*>(this)
5198+
->getImplicitSelfDecl(createIfNeeded);
52225199
}
5200+
ParamDecl *getImplicitSelfDecl(bool createIfNeeded=true);
52235201

52245202
/// Retrieve the declaration that this method overrides, if any.
52255203
AbstractFunctionDecl *getOverriddenDecl() const {
@@ -5346,7 +5324,6 @@ class FuncDecl : public AbstractFunctionDecl {
53465324
DeclName Name, SourceLoc NameLoc,
53475325
bool Throws, SourceLoc ThrowsLoc,
53485326
GenericParamList *GenericParams,
5349-
bool HasImplicitSelfDecl,
53505327
DeclContext *Parent,
53515328
ClangNode ClangN);
53525329

@@ -5358,7 +5335,6 @@ class FuncDecl : public AbstractFunctionDecl {
53585335
DeclName Name, SourceLoc NameLoc,
53595336
bool Throws, SourceLoc ThrowsLoc,
53605337
GenericParamList *GenericParams,
5361-
bool HasImplicitSelfDecl,
53625338
DeclContext *Parent);
53635339

53645340
static FuncDecl *create(ASTContext &Context, SourceLoc StaticLoc,
@@ -5367,7 +5343,6 @@ class FuncDecl : public AbstractFunctionDecl {
53675343
DeclName Name, SourceLoc NameLoc,
53685344
bool Throws, SourceLoc ThrowsLoc,
53695345
GenericParamList *GenericParams,
5370-
ParamDecl *SelfDecl,
53715346
ParameterList *ParameterList,
53725347
TypeLoc FnRetType, DeclContext *Parent,
53735348
ClangNode ClangN = ClangNode());
@@ -5550,7 +5525,6 @@ class AccessorDecl final : public FuncDecl {
55505525
SourceLoc staticLoc,
55515526
StaticSpellingKind staticSpelling,
55525527
bool throws, SourceLoc throwsLoc,
5553-
bool hasImplicitSelfDecl,
55545528
GenericParamList *genericParams,
55555529
DeclContext *parent,
55565530
ClangNode clangNode);
@@ -5566,7 +5540,6 @@ class AccessorDecl final : public FuncDecl {
55665540
StaticSpellingKind staticSpelling,
55675541
bool throws, SourceLoc throwsLoc,
55685542
GenericParamList *genericParams,
5569-
bool hasImplicitSelfDecl,
55705543
DeclContext *parent);
55715544

55725545
static AccessorDecl *create(ASTContext &ctx, SourceLoc declLoc,
@@ -5578,7 +5551,6 @@ class AccessorDecl final : public FuncDecl {
55785551
StaticSpellingKind staticSpelling,
55795552
bool throws, SourceLoc throwsLoc,
55805553
GenericParamList *genericParams,
5581-
ParamDecl *selfDecl,
55825554
ParameterList *parameterList,
55835555
TypeLoc fnRetType, DeclContext *parent,
55845556
ClangNode clangNode = ClangNode());
@@ -5886,7 +5858,7 @@ class ConstructorDecl : public AbstractFunctionDecl {
58865858
ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc,
58875859
OptionalTypeKind Failability, SourceLoc FailabilityLoc,
58885860
bool Throws, SourceLoc ThrowsLoc,
5889-
ParamDecl *SelfParam, ParameterList *BodyParams,
5861+
ParameterList *BodyParams,
58905862
GenericParamList *GenericParams,
58915863
DeclContext *Parent);
58925864

@@ -6057,8 +6029,7 @@ class DestructorDecl : public AbstractFunctionDecl {
60576029
ParamDecl *SelfDecl;
60586030

60596031
public:
6060-
DestructorDecl(SourceLoc DestructorLoc, ParamDecl *selfDecl,
6061-
DeclContext *Parent);
6032+
DestructorDecl(SourceLoc DestructorLoc, DeclContext *Parent);
60626033

60636034
ParamDecl **getImplicitSelfDeclStorage() { return &SelfDecl; }
60646035

lib/AST/ASTVerifier.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3013,13 +3013,15 @@ class Verifier : public ASTWalker {
30133013
Out << "mutating function in a class\n";
30143014
abort();
30153015
}
3016-
const ParamDecl *selfParam = FD->getImplicitSelfDecl();
3017-
if (!selfParam->isInOut()) {
3016+
const ParamDecl *selfParam = FD->getImplicitSelfDecl(
3017+
/*createIfNeeded=*/false);
3018+
if (selfParam && !selfParam->isInOut()) {
30183019
Out << "mutating function does not have inout 'self'\n";
30193020
abort();
30203021
}
30213022
} else {
3022-
const ParamDecl *selfParam = FD->getImplicitSelfDecl();
3023+
const ParamDecl *selfParam = FD->getImplicitSelfDecl(
3024+
/*createIfNeeded=*/false);
30233025
if (selfParam && selfParam->isInOut()) {
30243026
Out << "non-mutating function has inout 'self'\n";
30253027
abort();

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
313313
visitGenericParamList(AFD->getGenericParams());
314314
}
315315

316-
if (auto *PD = AFD->getImplicitSelfDecl())
316+
if (auto *PD = AFD->getImplicitSelfDecl(/*createIfNeeded=*/false))
317317
visit(PD);
318318
visit(AFD->getParameters());
319319

lib/AST/Builtins.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ getBuiltinFunction(Identifier Id, ArrayRef<Type> argTypes, Type ResType,
171171
Name, /*NameLoc=*/SourceLoc(),
172172
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
173173
/*GenericParams=*/nullptr,
174-
/*SelfDecl=*/nullptr,
175174
paramList,
176175
TypeLoc::withoutLoc(ResType), DC);
177176
FD->computeType(Info);
@@ -219,7 +218,6 @@ getBuiltinGenericFunction(Identifier Id,
219218
Name, /*NameLoc=*/SourceLoc(),
220219
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
221220
GenericParams,
222-
/*SelfDecl=*/nullptr,
223221
paramList,
224222
TypeLoc::withoutLoc(ResType), DC);
225223

0 commit comments

Comments
 (0)