Skip to content

Commit b6be6da

Browse files
committed
ASTGen: Translate associated type declarations
Plus tweak `DefaultDefinitionTypeRequest` caching to support querying the cached type when dumping. This fixes a crash where type computation is triggered in the dumper before import resolution in `-dump-parse` mode.
1 parent da427ad commit b6be6da

File tree

15 files changed

+206
-53
lines changed

15 files changed

+206
-53
lines changed

include/swift/AST/ASTContext.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,11 +1347,14 @@ class ASTContext final {
13471347
getInheritedConformance(Type type, ProtocolConformance *inherited);
13481348

13491349
/// Get the lazy data for the given declaration.
1350+
LazyContextData *getLazyContextData(const Decl *decl) const;
1351+
1352+
/// Get or otherwise allocate the lazy data for the given declaration.
13501353
///
13511354
/// \param lazyLoader If non-null, the lazy loader to use when creating the
13521355
/// lazy data. The pointer must either be null or be consistent
1353-
/// across all calls for the same \p func.
1354-
LazyContextData *getOrCreateLazyContextData(const DeclContext *decl,
1356+
/// across all calls for the same \p decl.
1357+
LazyContextData *getOrCreateLazyContextData(const Decl *decl,
13551358
LazyMemberLoader *lazyLoader);
13561359

13571360
/// Get the lazy iterable context for the given iterable declaration context.

include/swift/AST/CASTBridging.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,14 @@ BridgedDeclContextAndDecl ProtocolDecl_create(
372372
BridgedSourceLoc cNameLoc, BridgedArrayRef cPrimaryAssociatedTypeNames,
373373
BridgedArrayRef cInheritedTypes, BridgedSourceRange cBraceRange);
374374

375+
void *AssociatedTypeDecl_create(BridgedASTContext cContext,
376+
BridgedDeclContext cDeclContext,
377+
BridgedSourceLoc cAssociatedtypeKeywordLoc,
378+
BridgedIdentifier cName,
379+
BridgedSourceLoc cNameLoc,
380+
BridgedArrayRef cInheritedTypes,
381+
void *_Nullable opaqueDefaultType);
382+
375383
void *GenericParamList_create(BridgedASTContext cContext,
376384
BridgedSourceLoc cLAngleLoc,
377385
BridgedArrayRef params,

include/swift/AST/Decl.h

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
548548
IsOpaqueType : 1
549549
);
550550

551+
SWIFT_INLINE_BITFIELD_FULL(AssociatedTypeDecl, TypeDecl, 1,
552+
/// Whether we have computed the default type.
553+
IsDefaultDefinitionTypeComputed : 1
554+
);
555+
551556
SWIFT_INLINE_BITFIELD_EMPTY(GenericTypeDecl, TypeDecl);
552557

553558
SWIFT_INLINE_BITFIELD(TypeAliasDecl, GenericTypeDecl, 1+1,
@@ -3677,24 +3682,28 @@ class AssociatedTypeDecl : public TypeDecl {
36773682
SourceLoc KeywordLoc;
36783683

36793684
/// The default definition.
3680-
TypeRepr *DefaultDefinition;
3685+
TypeLoc DefaultDefinition;
36813686

36823687
/// The where clause attached to the associated type.
36833688
TrailingWhereClause *TrailingWhere;
36843689

3685-
LazyMemberLoader *Resolver = nullptr;
3686-
uint64_t ResolverContextData;
3687-
36883690
friend class DefaultDefinitionTypeRequest;
36893691

3690-
public:
36913692
AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name,
36923693
SourceLoc nameLoc, TypeRepr *defaultDefinition,
36933694
TrailingWhereClause *trailingWhere);
3694-
AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name,
3695-
SourceLoc nameLoc, TrailingWhereClause *trailingWhere,
3696-
LazyMemberLoader *definitionResolver,
3697-
uint64_t resolverData);
3695+
3696+
public:
3697+
static AssociatedTypeDecl *createParsed(ASTContext &ctx, DeclContext *dc,
3698+
SourceLoc keywordLoc, Identifier name,
3699+
SourceLoc nameLoc,
3700+
TypeRepr *defaultDefinition,
3701+
TrailingWhereClause *trailingWhere);
3702+
3703+
static AssociatedTypeDecl *createDeserialized(
3704+
ASTContext &ctx, DeclContext *dc, SourceLoc keywordLoc, Identifier name,
3705+
SourceLoc nameLoc, TrailingWhereClause *trailingWhere,
3706+
LazyMemberLoader *lazyLoader, uint64_t defaultDefinitionTypeData);
36983707

36993708
/// Get the protocol in which this associated type is declared.
37003709
ProtocolDecl *getProtocol() const {
@@ -3705,15 +3714,25 @@ class AssociatedTypeDecl : public TypeDecl {
37053714
bool hasDefaultDefinitionType() const {
37063715
// If we have a TypeRepr, return true immediately without kicking off
37073716
// a request.
3708-
return DefaultDefinition || getDefaultDefinitionType();
3717+
return DefaultDefinition.getTypeRepr() || getDefaultDefinitionType();
37093718
}
37103719

37113720
/// Retrieve the default definition type.
37123721
Type getDefaultDefinitionType() const;
37133722

3723+
/// Retrieve the default definition type if computed, `None` otherwise.
3724+
///
3725+
/// \Note Should only be used for dumping.
3726+
llvm::Optional<Type> getCachedDefaultDefinitionType() const;
3727+
3728+
private:
3729+
/// Set the computed default definition type.
3730+
void setDefaultDefinitionType(Type ty);
3731+
3732+
public:
37143733
/// Retrieve the default definition as written in the source.
37153734
TypeRepr *getDefaultDefinitionTypeRepr() const {
3716-
return DefaultDefinition;
3735+
return DefaultDefinition.getTypeRepr();
37173736
}
37183737

37193738
/// Retrieve the trailing where clause for this associated type, if any.

include/swift/AST/LazyResolver.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ class LazyIterableDeclContextData : public LazyContextData {
5757
uint64_t allConformancesData = 0;
5858
};
5959

60+
class LazyAssociatedTypeData : public LazyContextData {
61+
public:
62+
/// The context data used for loading the default type.
63+
uint64_t defaultDefinitionTypeData = 0;
64+
};
65+
6066
/// Context data for protocols.
6167
class LazyProtocolData : public LazyIterableDeclContextData {
6268
public:

include/swift/AST/TypeCheckRequests.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,10 @@ class RequirementSignatureRequest :
528528
};
529529

530530
/// Compute the default definition type of an associated type.
531-
class DefaultDefinitionTypeRequest :
532-
public SimpleRequest<DefaultDefinitionTypeRequest,
533-
Type(AssociatedTypeDecl *),
534-
RequestFlags::Cached> {
531+
class DefaultDefinitionTypeRequest
532+
: public SimpleRequest<DefaultDefinitionTypeRequest,
533+
Type(AssociatedTypeDecl *),
534+
RequestFlags::SeparatelyCached> {
535535
public:
536536
using SimpleRequest::SimpleRequest;
537537

@@ -544,6 +544,8 @@ class DefaultDefinitionTypeRequest :
544544
public:
545545
// Caching.
546546
bool isCached() const { return true; }
547+
llvm::Optional<Type> getCachedResult() const;
548+
void cacheResult(Type value) const;
547549
};
548550

549551
/// Describes the owner of a where clause, from which we can extract

lib/AST/ASTContext.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ struct ASTContext::Implementation {
341341
DelayedMissingWitnesses;
342342

343343
/// Stores information about lazy deserialization of various declarations.
344-
llvm::DenseMap<const DeclContext *, LazyContextData *> LazyContexts;
344+
llvm::DenseMap<const Decl *, LazyContextData *> LazyContexts;
345345

346346
/// A fake generic parameter list <Self> for parsing @opened archetypes
347347
/// in textual SIL.
@@ -2829,23 +2829,30 @@ PackConformance *PackConformance::get(PackType *conformingType,
28292829
return result;
28302830
}
28312831

2832-
LazyContextData *ASTContext::getOrCreateLazyContextData(
2833-
const DeclContext *dc,
2834-
LazyMemberLoader *lazyLoader) {
2835-
LazyContextData *&entry = getImpl().LazyContexts[dc];
2836-
if (entry) {
2832+
LazyContextData *ASTContext::getLazyContextData(const Decl *decl) const {
2833+
return getImpl().LazyContexts.lookup(decl);
2834+
}
2835+
2836+
LazyContextData *
2837+
ASTContext::getOrCreateLazyContextData(const Decl *decl,
2838+
LazyMemberLoader *lazyLoader) {
2839+
if (auto *data = getLazyContextData(decl)) {
28372840
// Make sure we didn't provide an incompatible lazy loader.
2838-
assert(!lazyLoader || lazyLoader == entry->loader);
2839-
return entry;
2841+
assert(!lazyLoader || lazyLoader == data->loader);
2842+
return data;
28402843
}
28412844

2845+
LazyContextData *&entry = getImpl().LazyContexts[decl];
2846+
28422847
// Create new lazy context data with the given loader.
28432848
assert(lazyLoader && "Queried lazy data for non-lazy iterable context");
2844-
if (isa<ProtocolDecl>(dc))
2849+
if (isa<ProtocolDecl>(decl)) {
28452850
entry = Allocate<LazyProtocolData>();
2846-
else {
2847-
assert(isa<NominalTypeDecl>(dc) || isa<ExtensionDecl>(dc));
2851+
} else if (isa<NominalTypeDecl>(decl) || isa<ExtensionDecl>(decl)) {
28482852
entry = Allocate<LazyIterableDeclContextData>();
2853+
} else {
2854+
assert(isa<AssociatedTypeDecl>(decl));
2855+
entry = Allocate<LazyAssociatedTypeData>();
28492856
}
28502857

28512858
entry->loader = lazyLoader;

lib/AST/ASTDumper.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,9 +1110,14 @@ namespace {
11101110

11111111
void visitAssociatedTypeDecl(AssociatedTypeDecl *decl, StringRef label) {
11121112
printCommon(decl, "associated_type_decl", label);
1113-
if (auto defaultDef = decl->getDefaultDefinitionType()) {
1114-
printFieldQuoted(defaultDef, "default");
1113+
1114+
StringRef fieldName("default");
1115+
if (auto defaultDef = decl->getCachedDefaultDefinitionType()) {
1116+
printFieldQuoted(*defaultDef, fieldName);
1117+
} else {
1118+
printField("<not computed>", fieldName);
11151119
}
1120+
11161121
printWhereRequirements(decl);
11171122
if (decl->overriddenDeclsComputed()) {
11181123
printFieldQuotedRaw([&](raw_ostream &OS) {

lib/AST/CASTBridging.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,26 @@ BridgedDeclContextAndDecl ProtocolDecl_create(
625625
return {bridgeDeclContext(decl), static_cast<Decl *>(decl)};
626626
}
627627

628+
void *AssociatedTypeDecl_create(BridgedASTContext cContext,
629+
BridgedDeclContext cDeclContext,
630+
BridgedSourceLoc cAssociatedtypeKeywordLoc,
631+
BridgedIdentifier cName,
632+
BridgedSourceLoc cNameLoc,
633+
BridgedArrayRef cInheritedTypes,
634+
void *_Nullable opaqueDefaultType) {
635+
ASTContext &context = convertASTContext(cContext);
636+
637+
auto *decl = AssociatedTypeDecl::createParsed(
638+
context, convertDeclContext(cDeclContext),
639+
convertSourceLoc(cAssociatedtypeKeywordLoc), convertIdentifier(cName),
640+
convertSourceLoc(cNameLoc), static_cast<TypeRepr *>(opaqueDefaultType),
641+
nullptr);
642+
decl->setInherited(
643+
context.AllocateCopy(convertToInheritedEntries(cInheritedTypes)));
644+
645+
return static_cast<Decl *>(decl);
646+
}
647+
628648
void *OptionalTypeRepr_create(BridgedASTContext cContext, void *base,
629649
BridgedSourceLoc cQuestionLoc) {
630650
ASTContext &context = convertASTContext(cContext);

lib/AST/Decl.cpp

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5234,18 +5234,48 @@ AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
52345234
TrailingWhereClause *trailingWhere)
52355235
: TypeDecl(DeclKind::AssociatedType, dc, name, nameLoc, { }),
52365236
KeywordLoc(keywordLoc), DefaultDefinition(defaultDefinition),
5237-
TrailingWhere(trailingWhere) {}
5237+
TrailingWhere(trailingWhere) {
5238+
Bits.AssociatedTypeDecl.IsDefaultDefinitionTypeComputed = false;
5239+
}
52385240

5239-
AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
5240-
Identifier name, SourceLoc nameLoc,
5241-
TrailingWhereClause *trailingWhere,
5242-
LazyMemberLoader *definitionResolver,
5243-
uint64_t resolverData)
5244-
: TypeDecl(DeclKind::AssociatedType, dc, name, nameLoc, { }),
5245-
KeywordLoc(keywordLoc), DefaultDefinition(nullptr),
5246-
TrailingWhere(trailingWhere), Resolver(definitionResolver),
5247-
ResolverContextData(resolverData) {
5248-
assert(Resolver && "missing resolver");
5241+
AssociatedTypeDecl *
5242+
AssociatedTypeDecl::createParsed(ASTContext &ctx, DeclContext *dc,
5243+
SourceLoc keywordLoc, Identifier name,
5244+
SourceLoc nameLoc, TypeRepr *defaultDefinition,
5245+
TrailingWhereClause *trailingWhere) {
5246+
auto *decl = new (ctx) AssociatedTypeDecl(dc, keywordLoc, name, nameLoc,
5247+
defaultDefinition, trailingWhere);
5248+
5249+
// Sort out this trivial case now to enable the AST dumper to differentiate
5250+
// between a nonexistent and null default type without having to trigger a
5251+
// request.
5252+
if (!defaultDefinition)
5253+
decl->setDefaultDefinitionType(nullptr);
5254+
5255+
return decl;
5256+
}
5257+
5258+
AssociatedTypeDecl *AssociatedTypeDecl::createDeserialized(
5259+
ASTContext &ctx, DeclContext *dc, SourceLoc keywordLoc, Identifier name,
5260+
SourceLoc nameLoc, TrailingWhereClause *trailingWhere,
5261+
LazyMemberLoader *lazyLoader, uint64_t defaultDefinitionTypeData) {
5262+
assert(lazyLoader && "missing lazy member loader");
5263+
auto *decl = new (ctx)
5264+
AssociatedTypeDecl(dc, keywordLoc, name, nameLoc,
5265+
/*defaultDefinition*/ nullptr, trailingWhere);
5266+
5267+
// Sort out this trivial case now to enable the AST dumper to differentiate
5268+
// between a nonexistent and null default type without having to trigger a
5269+
// request. '0' is the sentinel ID for no data.
5270+
if (defaultDefinitionTypeData == 0) {
5271+
decl->setDefaultDefinitionType(nullptr);
5272+
} else {
5273+
auto *data = static_cast<LazyAssociatedTypeData *>(
5274+
ctx.getOrCreateLazyContextData(decl, lazyLoader));
5275+
data->defaultDefinitionTypeData = defaultDefinitionTypeData;
5276+
}
5277+
5278+
return decl;
52495279
}
52505280

52515281
Type AssociatedTypeDecl::getDefaultDefinitionType() const {
@@ -5254,6 +5284,19 @@ Type AssociatedTypeDecl::getDefaultDefinitionType() const {
52545284
Type());
52555285
}
52565286

5287+
llvm::Optional<Type>
5288+
AssociatedTypeDecl::getCachedDefaultDefinitionType() const {
5289+
if (Bits.AssociatedTypeDecl.IsDefaultDefinitionTypeComputed)
5290+
return DefaultDefinition.getType();
5291+
5292+
return llvm::None;
5293+
}
5294+
5295+
void AssociatedTypeDecl::setDefaultDefinitionType(Type ty) {
5296+
DefaultDefinition.setType(ty);
5297+
Bits.AssociatedTypeDecl.IsDefaultDefinitionTypeComputed = true;
5298+
}
5299+
52575300
SourceRange AssociatedTypeDecl::getSourceRange() const {
52585301
SourceLoc endLoc;
52595302
if (auto TWC = getTrailingWhereClause()) {

lib/AST/TypeCheckRequests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,20 @@ void RequirementSignatureRequest::cacheResult(RequirementSignature value) const
375375
proto->setRequirementSignature(value);
376376
}
377377

378+
//----------------------------------------------------------------------------//
379+
// DefaultDefinitionTypeRequest computation.
380+
//----------------------------------------------------------------------------//
381+
382+
llvm::Optional<Type> DefaultDefinitionTypeRequest::getCachedResult() const {
383+
auto *decl = std::get<0>(getStorage());
384+
return decl->getCachedDefaultDefinitionType();
385+
}
386+
387+
void DefaultDefinitionTypeRequest::cacheResult(Type value) const {
388+
auto *decl = std::get<0>(getStorage());
389+
decl->setDefaultDefinitionType(value);
390+
}
391+
378392
//----------------------------------------------------------------------------//
379393
// Requirement computation.
380394
//----------------------------------------------------------------------------//

0 commit comments

Comments
 (0)