Skip to content

Commit e2a49f4

Browse files
committed
Rework the storage of generic parameter lists in generic contexts.
In generic contexts, rework the storage for generic parameter lists to make it more explicit when we have parsed vs. synthesized vs. parsed-and-type-checked generic parameter lists.
1 parent cc3fc4a commit e2a49f4

File tree

4 files changed

+44
-13
lines changed

4 files changed

+44
-13
lines changed

include/swift/AST/Decl.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,21 @@ void *allocateMemoryForDecl(AllocatorTy &allocator, size_t baseSize,
10611061
class alignas(8) _GenericContext {
10621062
// Not really public. See GenericContext.
10631063
public:
1064-
llvm::PointerIntPair<GenericParamList *, 1, bool> GenericParamsAndBit;
1064+
/// The state of the generic parameters.
1065+
enum class GenericParamsState: uint8_t {
1066+
/// The stored generic parameters represent parsed generic parameters,
1067+
/// written in the source.
1068+
Parsed = 0,
1069+
/// The stored generic parameters represent generic parameters that are
1070+
/// synthesized by the type checker but were not written in the source.
1071+
TypeChecked = 1,
1072+
/// The stored generic parameters represent both the parsed and
1073+
/// type-checked generic parameters.
1074+
ParsedAndTypeChecked = 2,
1075+
};
1076+
1077+
llvm::PointerIntPair<GenericParamList *, 2, GenericParamsState>
1078+
GenericParamsAndState;
10651079

10661080
/// The trailing where clause.
10671081
///

lib/AST/Decl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ GenericContext::GenericContext(DeclContextKind Kind, DeclContext *Parent,
985985
: _GenericContext(), DeclContext(Kind, Parent) {
986986
if (Params) {
987987
Params->setDeclContext(this);
988-
GenericParamsAndBit.setPointerAndInt(Params, false);
988+
GenericParamsAndState.setPointerAndInt(Params, GenericParamsState::Parsed);
989989
}
990990
}
991991

@@ -1006,9 +1006,14 @@ GenericParamList *GenericContext::getGenericParams() const {
10061006
}
10071007

10081008
GenericParamList *GenericContext::getParsedGenericParams() const {
1009-
if (GenericParamsAndBit.getInt())
1009+
switch (GenericParamsAndState.getInt()) {
1010+
case GenericParamsState::Parsed:
1011+
case GenericParamsState::ParsedAndTypeChecked:
1012+
return GenericParamsAndState.getPointer();
1013+
1014+
case GenericParamsState::TypeChecked:
10101015
return nullptr;
1011-
return GenericParamsAndBit.getPointer();
1016+
}
10121017
}
10131018

10141019
bool GenericContext::hasComputedGenericSignature() const {

lib/AST/NameLookup.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,7 +2597,9 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
25972597
outerParams->setDepth(depth--);
25982598

25992599
return genericParams;
2600-
} else if (auto *proto = dyn_cast<ProtocolDecl>(value)) {
2600+
}
2601+
2602+
if (auto *proto = dyn_cast<ProtocolDecl>(value)) {
26012603
// The generic parameter 'Self'.
26022604
auto &ctx = value->getASTContext();
26032605
auto selfId = ctx.Id_Self;
@@ -2615,7 +2617,8 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
26152617
SourceLoc());
26162618
return result;
26172619
}
2618-
return nullptr;
2620+
2621+
return value->getParsedGenericParams();
26192622
}
26202623

26212624
NominalTypeDecl *

lib/AST/NameLookupRequests.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,22 +212,31 @@ void GetDestructorRequest::cacheResult(DestructorDecl *value) const {
212212
//----------------------------------------------------------------------------//
213213

214214
Optional<GenericParamList *> GenericParamListRequest::getCachedResult() const {
215+
using GenericParamsState = GenericContext::GenericParamsState;
215216
auto *decl = std::get<0>(getStorage());
216-
if (auto *params = decl->GenericParamsAndBit.getPointer())
217-
return params;
217+
switch (decl->GenericParamsAndState.getInt()) {
218+
case GenericParamsState::TypeChecked:
219+
case GenericParamsState::ParsedAndTypeChecked:
220+
return decl->GenericParamsAndState.getPointer();
218221

219-
if (decl->GenericParamsAndBit.getInt())
220-
return nullptr;
221-
222-
return None;
222+
case GenericParamsState::Parsed:
223+
return None;
224+
}
223225
}
224226

225227
void GenericParamListRequest::cacheResult(GenericParamList *params) const {
228+
using GenericParamsState = GenericContext::GenericParamsState;
226229
auto *context = std::get<0>(getStorage());
227230
if (params)
228231
params->setDeclContext(context);
229232

230-
context->GenericParamsAndBit.setPointerAndInt(params, true);
233+
assert(context->GenericParamsAndState.getInt() == GenericParamsState::Parsed);
234+
bool hadParsedGenericParams =
235+
context->GenericParamsAndState.getPointer() != nullptr;
236+
auto newState = hadParsedGenericParams
237+
? GenericParamsState::ParsedAndTypeChecked
238+
: GenericParamsState::TypeChecked;
239+
context->GenericParamsAndState.setPointerAndInt(params, newState);
231240
}
232241

233242
//----------------------------------------------------------------------------//

0 commit comments

Comments
 (0)