Skip to content

Commit a9315e9

Browse files
authored
Merge pull request #19825 from DougGregor/immortal-type-checker
[Type checker] Keep the type checker alive as long as the ASTContext is.
2 parents 2a18ea7 + 264b680 commit a9315e9

19 files changed

+162
-186
lines changed

include/swift/AST/ASTContext.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,35 @@ class ASTContext final {
400400
/// Set a new stats reporter.
401401
void setStatsReporter(UnifiedStatsReporter *stats);
402402

403+
/// Creates a new lazy resolver by passing the ASTContext and the other
404+
/// given arguments to a newly-allocated instance of \c ResolverType.
405+
///
406+
/// \returns true if a new lazy resolver was created, false if there was
407+
/// already a lazy resolver registered.
408+
template<typename ResolverType, typename ... Args>
409+
bool createLazyResolverIfMissing(Args && ...args) {
410+
if (getLazyResolver())
411+
return false;
412+
413+
setLazyResolver(new ResolverType(*this, std::forward<Args>(args)...));
414+
return true;
415+
}
416+
417+
/// Remove the lazy resolver, if there is one.
418+
///
419+
/// FIXME: We probably don't ever want to do this.
420+
void removeLazyResolver() {
421+
setLazyResolver(nullptr);
422+
}
423+
403424
/// Retrieve the lazy resolver for this context.
404425
LazyResolver *getLazyResolver() const;
405426

427+
private:
406428
/// Set the lazy resolver for this context.
407429
void setLazyResolver(LazyResolver *resolver);
408430

431+
public:
409432
/// Add a lazy parser for resolving members later.
410433
void addLazyParser(LazyMemberParser *parser);
411434

include/swift/Sema/IDETypeChecking.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace swift {
3030
class ExtensionDecl;
3131
class ProtocolDecl;
3232
class Type;
33+
class TypeChecker;
3334
class DeclContext;
3435
class ConcreteDeclRef;
3536
class ValueDecl;
@@ -123,11 +124,11 @@ namespace swift {
123124
/// \returns true on success, false on error.
124125
bool typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD);
125126

126-
/// A unique_ptr for LazyResolver that can perform additional cleanup.
127-
using OwnedResolver = std::unique_ptr<LazyResolver, void(*)(LazyResolver*)>;
128-
129-
/// Creates a lazy type resolver for use in lookups.
130-
OwnedResolver createLazyResolver(ASTContext &Ctx);
127+
/// Creates a type checker instance on the given AST context, if it
128+
/// doesn't already have one.
129+
///
130+
/// \returns a reference to the type checker instance.
131+
TypeChecker &createTypeChecker(ASTContext &Ctx);
131132

132133
struct ExtensionInfo {
133134
// The extension with the declarations to apply.

lib/AST/ASTContext.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
428428
ASTContext::Implementation::Implementation()
429429
: IdentifierTable(Allocator), TheSyntaxArena(new SyntaxArena()) {}
430430
ASTContext::Implementation::~Implementation() {
431+
delete Resolver;
432+
431433
for (auto &cleanup : Cleanups)
432434
cleanup();
433435
}
@@ -579,13 +581,10 @@ LazyResolver *ASTContext::getLazyResolver() const {
579581

580582
/// Set the lazy resolver for this context.
581583
void ASTContext::setLazyResolver(LazyResolver *resolver) {
582-
if (resolver) {
583-
assert(getImpl().Resolver == nullptr && "already have a resolver");
584-
getImpl().Resolver = resolver;
585-
} else {
586-
assert(getImpl().Resolver != nullptr && "no resolver to remove");
587-
getImpl().Resolver = resolver;
588-
}
584+
if (auto existing = getImpl().Resolver)
585+
delete existing;
586+
587+
getImpl().Resolver = resolver;
589588
}
590589

591590
void ASTContext::addLazyParser(LazyMemberParser *lazyParser) {

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
849849
TheSILModule ? &SILContext : nullptr, &PersistentState,
850850
DelayedParseCB);
851851

852-
if (mainIsPrimary) {
852+
if (mainIsPrimary && (Done || CurTUElem < MainFile.Decls.size())) {
853853
switch (LimitStage) {
854854
case SourceFile::Parsing:
855855
case SourceFile::Parsed:

lib/IDE/CodeCompletion.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,7 @@ static bool hasTrivialTrailingClosure(const FuncDecl *FD,
15801580
class CompletionLookup final : public swift::VisibleDeclConsumer {
15811581
CodeCompletionResultSink &Sink;
15821582
ASTContext &Ctx;
1583-
OwnedResolver TypeResolver;
1583+
LazyResolver *TypeResolver = nullptr;
15841584
const DeclContext *CurrDeclContext;
15851585
ClangImporter *Importer;
15861586
CodeCompletionContext *CompletionContext;
@@ -1723,11 +1723,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
17231723
ASTContext &Ctx,
17241724
const DeclContext *CurrDeclContext,
17251725
CodeCompletionContext *CompletionContext = nullptr)
1726-
: Sink(Sink), Ctx(Ctx),
1727-
TypeResolver(createLazyResolver(Ctx)), CurrDeclContext(CurrDeclContext),
1726+
: Sink(Sink), Ctx(Ctx), CurrDeclContext(CurrDeclContext),
17281727
Importer(static_cast<ClangImporter *>(CurrDeclContext->getASTContext().
17291728
getClangModuleLoader())),
17301729
CompletionContext(CompletionContext) {
1730+
(void)createTypeChecker(Ctx);
1731+
TypeResolver = Ctx.getLazyResolver();
17311732

17321733
// Determine if we are doing code completion inside a static method.
17331734
if (CurrDeclContext) {
@@ -1737,10 +1738,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
17371738
}
17381739
}
17391740

1740-
void discardTypeResolver() {
1741-
TypeResolver.reset();
1742-
}
1743-
17441741
void setHaveDot(SourceLoc DotLoc) {
17451742
HaveDot = true;
17461743
this->DotLoc = DotLoc;
@@ -2095,7 +2092,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
20952092
if (Conformance && Conformance->isConcrete()) {
20962093
return Conformance->getConcrete()
20972094
->getTypeWitness(const_cast<AssociatedTypeDecl *>(ATD),
2098-
TypeResolver.get());
2095+
nullptr);
20992096
}
21002097
}
21012098
}
@@ -2624,7 +2621,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26242621
SmallVector<ValueDecl *, 16> initializers;
26252622
if (CurrDeclContext->lookupQualified(type, DeclBaseName::createConstructor(),
26262623
NL_QualifiedDefault,
2627-
TypeResolver.get(), initializers)) {
2624+
TypeResolver, initializers)) {
26282625
for (auto *init : initializers) {
26292626
if (shouldHideDeclFromCompletionResults(init))
26302627
continue;
@@ -3121,7 +3118,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31213118
if (isIUO) {
31223119
if (Type Unwrapped = ExprType->getOptionalObjectType()) {
31233120
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
3124-
TypeResolver.get(), IncludeInstanceMembers);
3121+
TypeResolver, IncludeInstanceMembers);
31253122
return true;
31263123
}
31273124
assert(IsUnwrappedOptional && "IUOs should be optional if not bound/forced");
@@ -3141,7 +3138,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31413138
CodeCompletionResult::MaxNumBytesToErase) {
31423139
if (!tryTupleExprCompletions(Unwrapped)) {
31433140
lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
3144-
TypeResolver.get(),
3141+
TypeResolver,
31453142
IncludeInstanceMembers);
31463143
}
31473144
}
@@ -3181,7 +3178,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31813178
tryUnwrappedCompletions(ExprType, isIUO);
31823179

31833180
lookupVisibleMemberDecls(*this, ExprType, CurrDeclContext,
3184-
TypeResolver.get(), IncludeInstanceMembers);
3181+
TypeResolver, IncludeInstanceMembers);
31853182
}
31863183

31873184
template <typename T>
@@ -3690,7 +3687,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
36903687
Kind = LookupKind::ValueInDeclContext;
36913688
NeedLeadingDot = false;
36923689
FilteredDeclConsumer Consumer(*this, Filter);
3693-
lookupVisibleDecls(Consumer, CurrDeclContext, TypeResolver.get(),
3690+
lookupVisibleDecls(Consumer, CurrDeclContext, TypeResolver,
36943691
/*IncludeTopLevel=*/IncludeTopLevel, Loc);
36953692
if (RequestCache)
36963693
RequestedCachedResults = RequestedResultsTy::toplevelResults();
@@ -3823,7 +3820,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
38233820
llvm::SaveAndRestore<Type> SaveType(ExprType, baseType);
38243821
llvm::SaveAndRestore<bool> SaveUnresolved(IsUnresolvedMember, true);
38253822
lookupVisibleMemberDecls(consumer, baseType, CurrDeclContext,
3826-
TypeResolver.get(),
3823+
TypeResolver,
38273824
/*includeInstanceMembers=*/false);
38283825
}
38293826

@@ -4026,7 +4023,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
40264023
NeedLeadingDot = !HaveDot;
40274024
Type MetaBase = MetatypeType::get(BaseType);
40284025
lookupVisibleMemberDecls(*this, MetaBase,
4029-
CurrDeclContext, TypeResolver.get(),
4026+
CurrDeclContext, TypeResolver,
40304027
IncludeInstanceMembers);
40314028
addKeyword("Type", MetaBase);
40324029
}
@@ -4090,7 +4087,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
40904087

40914088
void getTypeCompletionsInDeclContext(SourceLoc Loc) {
40924089
Kind = LookupKind::TypeInDeclContext;
4093-
lookupVisibleDecls(*this, CurrDeclContext, TypeResolver.get(),
4090+
lookupVisibleDecls(*this, CurrDeclContext, TypeResolver,
40944091
/*IncludeTopLevel=*/false, Loc);
40954092

40964093
RequestedCachedResults =
@@ -4125,8 +4122,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
41254122

41264123
class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41274124
CodeCompletionResultSink &Sink;
4128-
OwnedResolver TypeResolver;
41294125
const DeclContext *CurrDeclContext;
4126+
LazyResolver *TypeResolver;
41304127
SmallVectorImpl<StringRef> &ParsedKeywords;
41314128

41324129
bool hasFuncIntroducer = false;
@@ -4141,8 +4138,11 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41414138
CompletionOverrideLookup(CodeCompletionResultSink &Sink, ASTContext &Ctx,
41424139
const DeclContext *CurrDeclContext,
41434140
SmallVectorImpl<StringRef> &ParsedKeywords)
4144-
: Sink(Sink), TypeResolver(createLazyResolver(Ctx)),
4141+
: Sink(Sink),
41454142
CurrDeclContext(CurrDeclContext), ParsedKeywords(ParsedKeywords) {
4143+
(void)createTypeChecker(Ctx);
4144+
TypeResolver = Ctx.getLazyResolver();
4145+
41464146
hasFuncIntroducer = isKeywordSpecified("func");
41474147
hasVarIntroducer = isKeywordSpecified("var") ||
41484148
isKeywordSpecified("let");
@@ -4414,7 +4414,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
44144414
Type CurrTy = CurrDeclContext->getDeclaredTypeInContext();
44154415
if (CurrTy && !CurrTy->is<ErrorType>()) {
44164416
lookupVisibleMemberDecls(*this, CurrTy, CurrDeclContext,
4417-
TypeResolver.get(),
4417+
TypeResolver,
44184418
/*includeInstanceMembers=*/false);
44194419
addDesignatedInitializers(CurrTy);
44204420
addAssociatedTypes(CurrTy);
@@ -5576,7 +5576,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
55765576
}
55775577

55785578
case CompletionKind::NominalMemberBeginning: {
5579-
Lookup.discardTypeResolver();
55805579
CompletionOverrideLookup OverrideLookup(CompletionContext.getResultSink(),
55815580
P.Context, CurDeclContext,
55825581
ParsedKeywords);
@@ -5738,15 +5737,12 @@ void CodeCompletionCallbacksImpl::doneParsing() {
57385737
};
57395738

57405739
if (Request.TheModule) {
5741-
Lookup.discardTypeResolver();
5742-
57435740
// FIXME: actually check imports.
57445741
const_cast<ModuleDecl*>(Request.TheModule)
57455742
->forAllVisibleModules({}, handleImport);
57465743
} else {
57475744
// Add results from current module.
57485745
Lookup.getToplevelCompletions(Request.OnlyTypes);
5749-
Lookup.discardTypeResolver();
57505746

57515747
// Add results for all imported modules.
57525748
SmallVector<ModuleDecl::ImportedModule, 4> Imports;

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3664,13 +3664,7 @@ bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy,
36643664
BaseTy->hasUnboundGenericType())
36653665
return true;
36663666

3667-
std::unique_ptr<TypeChecker> CreatedTC;
3668-
// If the current ast context has no type checker, create one for it.
3669-
auto *TC = static_cast<TypeChecker*>(DC.getASTContext().getLazyResolver());
3670-
if (!TC) {
3671-
CreatedTC.reset(new TypeChecker(DC.getASTContext()));
3672-
TC = CreatedTC.get();
3673-
}
3667+
TypeChecker *TC = &createTypeChecker(DC.getASTContext());
36743668

36753669
ConstraintSystemOptions Options;
36763670
ConstraintSystem CS(*TC, &DC, Options);
@@ -3696,14 +3690,9 @@ bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy,
36963690
static bool canSatisfy(Type type1, Type type2, bool openArchetypes,
36973691
ConstraintKind kind, DeclContext *dc) {
36983692
std::unique_ptr<TypeChecker> CreatedTC;
3699-
// If the current ASTContext has no type checker, create one for it.
3700-
auto *TC = static_cast<TypeChecker*>(dc->getASTContext().getLazyResolver());
3701-
if (!TC) {
3702-
CreatedTC.reset(new TypeChecker(dc->getASTContext()));
3703-
TC = CreatedTC.get();
3704-
}
3705-
return TC->typesSatisfyConstraint(type1, type2, openArchetypes, kind, dc,
3706-
/*unwrappedIUO=*/nullptr);
3693+
auto &TC = TypeChecker::createForContext(dc->getASTContext());
3694+
return TC.typesSatisfyConstraint(type1, type2, openArchetypes, kind, dc,
3695+
/*unwrappedIUO=*/nullptr);
37073696
}
37083697

37093698
bool swift::canPossiblyEqual(Type T1, Type T2, DeclContext &DC) {
@@ -3765,12 +3754,8 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
37653754
ResolvedMemberResult Result;
37663755
std::unique_ptr<TypeChecker> CreatedTC;
37673756
// If the current ast context has no type checker, create one for it.
3768-
auto *TC = static_cast<TypeChecker*>(DC.getASTContext().getLazyResolver());
3769-
if (!TC) {
3770-
CreatedTC.reset(new TypeChecker(DC.getASTContext()));
3771-
TC = CreatedTC.get();
3772-
}
3773-
ConstraintSystem CS(*TC, &DC, None);
3757+
auto &TC = TypeChecker::createForContext(DC.getASTContext());
3758+
ConstraintSystem CS(TC, &DC, None);
37743759

37753760
// Look up all members of BaseTy with the given Name.
37763761
MemberLookupResult LookupResult = CS.performMemberLookup(

lib/Sema/DebuggerTestingTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class DebuggerTestingTransform : public ASTWalker {
215215
CheckExpectExpr->setThrows(false);
216216

217217
// Create the closure.
218-
TypeChecker TC{Ctx};
218+
TypeChecker &TC = TypeChecker::createForContext(Ctx);
219219
auto *Params = ParameterList::createEmpty(Ctx);
220220
auto *Closure = new (Ctx)
221221
ClosureExpr(Params, SourceLoc(), SourceLoc(), SourceLoc(), TypeLoc(),

lib/Sema/InstrumenterSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ bool InstrumenterBase::doTypeCheckImpl(ASTContext &Ctx, DeclContext *DC,
8181
DiagnosticSuppression suppression(Ctx.Diags);
8282
ErrorGatherer errorGatherer(Ctx.Diags);
8383

84-
TypeChecker TC(Ctx);
84+
TypeChecker &TC = TypeChecker::createForContext(Ctx);
8585

8686
TC.typeCheckExpression(parsedExpr, DC);
8787

lib/Sema/PCMacro.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ class Instrumenter : InstrumenterBase {
322322

323323
if (NB != B) {
324324
FD->setBody(NB);
325-
TypeChecker(Context).checkFunctionErrorHandling(FD);
325+
TypeChecker::createForContext(Context).checkFunctionErrorHandling(FD);
326326
}
327327
}
328328
} else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
@@ -668,7 +668,7 @@ void swift::performPCMacro(SourceFile &SF, TopLevelContext &TLC) {
668668
BraceStmt *NewBody = I.transformBraceStmt(Body, true);
669669
if (NewBody != Body) {
670670
TLCD->setBody(NewBody);
671-
TypeChecker TC(ctx);
671+
TypeChecker &TC = TypeChecker::createForContext(ctx);
672672
TC.checkTopLevelErrorHandling(TLCD);
673673
TC.contextualizeTopLevelCode(TLC,
674674
SmallVector<Decl *, 1>(1, TLCD));

lib/Sema/PlaygroundTransform.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class Instrumenter : InstrumenterBase {
280280
BraceStmt *NB = transformBraceStmt(B);
281281
if (NB != B) {
282282
FD->setBody(NB);
283-
TypeChecker(Context).checkFunctionErrorHandling(FD);
283+
TypeChecker::createForContext(Context).checkFunctionErrorHandling(FD);
284284
}
285285
}
286286
} else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
@@ -893,7 +893,7 @@ void swift::performPlaygroundTransform(SourceFile &SF, bool HighPerformance) {
893893
BraceStmt *NewBody = I.transformBraceStmt(Body);
894894
if (NewBody != Body) {
895895
FD->setBody(NewBody);
896-
TypeChecker(ctx).checkFunctionErrorHandling(FD);
896+
TypeChecker::createForContext(ctx).checkFunctionErrorHandling(FD);
897897
}
898898
return false;
899899
}
@@ -906,7 +906,8 @@ void swift::performPlaygroundTransform(SourceFile &SF, bool HighPerformance) {
906906
BraceStmt *NewBody = I.transformBraceStmt(Body, true);
907907
if (NewBody != Body) {
908908
TLCD->setBody(NewBody);
909-
TypeChecker(ctx).checkTopLevelErrorHandling(TLCD);
909+
TypeChecker::createForContext(ctx)
910+
.checkTopLevelErrorHandling(TLCD);
910911
}
911912
return false;
912913
}

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,7 @@ static bool diagnoseAvailability(IdentTypeRepr *IdType,
14771477
auto componentRange = IdType->getComponentRange();
14781478
for (auto comp : componentRange) {
14791479
if (auto *typeDecl = comp->getBoundDecl()) {
1480-
// FIXME: Need to eliminate the type checker argument.
1480+
assert(ctx.getLazyResolver() && "Must have a type checker!");
14811481
TypeChecker &tc = static_cast<TypeChecker &>(*ctx.getLazyResolver());
14821482
if (diagnoseDeclAvailability(typeDecl, tc, DC, comp->getIdLoc(),
14831483
AllowPotentiallyUnavailableProtocol,

0 commit comments

Comments
 (0)