Skip to content

Commit 7907962

Browse files
authored
Merge pull request #6086 from DougGregor/baby-steps-away-from-parent-environment
[Type checker] Reduce/isolate reuse of parent generic environments
2 parents 70d818b + 553216a commit 7907962

31 files changed

+139
-179
lines changed

include/swift/AST/DeclContext.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,11 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
198198
friend struct ::llvm::cast_convert_val;
199199

200200
static DeclContext *castDeclToDeclContext(const Decl *D);
201-
201+
202+
/// If this DeclContext is a GenericType declaration or an
203+
/// extension thereof, return the GenericTypeDecl.
204+
GenericTypeDecl *getAsTypeOrTypeExtensionContext() const;
205+
202206
public:
203207
DeclContext(DeclContextKind Kind, DeclContext *Parent)
204208
: ParentAndKind(Parent, Kind) {
@@ -232,20 +236,13 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
232236

233237
/// \returns true if this is a type context, e.g., a struct, a class, an
234238
/// enum, a protocol, or an extension.
235-
bool isTypeContext() const {
236-
return getContextKind() == DeclContextKind::GenericTypeDecl ||
237-
getContextKind() == DeclContextKind::ExtensionDecl;
238-
}
239+
bool isTypeContext() const;
239240

240241
/// \brief Determine whether this is an extension context.
241242
bool isExtensionContext() const {
242243
return getContextKind() == DeclContextKind::ExtensionDecl;
243244
}
244245

245-
/// If this DeclContext is a GenericType declaration or an
246-
/// extension thereof, return the GenericTypeDecl.
247-
GenericTypeDecl *getAsGenericTypeOrGenericTypeExtensionContext() const;
248-
249246
/// If this DeclContext is a NominalType declaration or an
250247
/// extension thereof, return the NominalTypeDecl.
251248
NominalTypeDecl *getAsNominalTypeOrNominalTypeExtensionContext() const;

lib/AST/ConformanceLookupTable.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,8 +801,7 @@ ProtocolConformance *ConformanceLookupTable::getConformance(
801801
return nullptr;
802802

803803
auto *conformingNominal =
804-
cast<NominalTypeDecl>(conformingDC->
805-
getAsGenericTypeOrGenericTypeExtensionContext());
804+
conformingDC->getAsNominalTypeOrNominalTypeExtensionContext();
806805

807806
// Form the conformance.
808807
Type type = entry->getDeclContext()->getDeclaredTypeInContext();

lib/AST/DeclContext.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ ASTContext &DeclContext::getASTContext() const {
4040
}
4141

4242
GenericTypeDecl *
43-
DeclContext::getAsGenericTypeOrGenericTypeExtensionContext() const {
43+
DeclContext::getAsTypeOrTypeExtensionContext() const {
4444
switch (getContextKind()) {
4545
case DeclContextKind::Module:
4646
case DeclContextKind::FileUnit:
@@ -78,32 +78,28 @@ DeclContext::getAsGenericTypeOrGenericTypeExtensionContext() const {
7878
/// extension thereof, return the NominalTypeDecl.
7979
NominalTypeDecl *DeclContext::
8080
getAsNominalTypeOrNominalTypeExtensionContext() const {
81-
auto decl = getAsGenericTypeOrGenericTypeExtensionContext();
81+
auto decl = getAsTypeOrTypeExtensionContext();
8282
return dyn_cast_or_null<NominalTypeDecl>(decl);
8383
}
8484

8585

8686
ClassDecl *DeclContext::getAsClassOrClassExtensionContext() const {
87-
return dyn_cast_or_null<ClassDecl>(
88-
getAsGenericTypeOrGenericTypeExtensionContext());
87+
return dyn_cast_or_null<ClassDecl>(getAsTypeOrTypeExtensionContext());
8988
}
9089

9190
EnumDecl *DeclContext::getAsEnumOrEnumExtensionContext() const {
92-
return dyn_cast_or_null<EnumDecl>(
93-
getAsGenericTypeOrGenericTypeExtensionContext());
91+
return dyn_cast_or_null<EnumDecl>(getAsTypeOrTypeExtensionContext());
9492
}
9593

9694
ProtocolDecl *DeclContext::getAsProtocolOrProtocolExtensionContext() const {
97-
return dyn_cast_or_null<ProtocolDecl>(
98-
getAsGenericTypeOrGenericTypeExtensionContext());
95+
return dyn_cast_or_null<ProtocolDecl>(getAsTypeOrTypeExtensionContext());
9996
}
10097

10198
ProtocolDecl *DeclContext::getAsProtocolExtensionContext() const {
10299
if (getContextKind() != DeclContextKind::ExtensionDecl)
103100
return nullptr;
104101

105-
return dyn_cast_or_null<ProtocolDecl>(
106-
getAsGenericTypeOrGenericTypeExtensionContext());
102+
return dyn_cast_or_null<ProtocolDecl>(getAsTypeOrTypeExtensionContext());
107103
}
108104

109105
GenericTypeParamType *DeclContext::getProtocolSelfType() const {
@@ -357,6 +353,11 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() {
357353
}
358354
}
359355

356+
bool DeclContext::isTypeContext() const {
357+
return isa<NominalTypeDecl>(this) ||
358+
getContextKind() == DeclContextKind::ExtensionDecl;
359+
}
360+
360361
DeclContext *DeclContext::getInnermostTypeContext() {
361362
DeclContext *Result = this;
362363
while (true) {
@@ -374,8 +375,14 @@ DeclContext *DeclContext::getInnermostTypeContext() {
374375
case DeclContextKind::FileUnit:
375376
return nullptr;
376377

377-
case DeclContextKind::ExtensionDecl:
378378
case DeclContextKind::GenericTypeDecl:
379+
if (isa<TypeAliasDecl>(Result)) {
380+
Result = Result->getParent();
381+
continue;
382+
}
383+
return Result;
384+
385+
case DeclContextKind::ExtensionDecl:
379386
return Result;
380387
}
381388
}

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,8 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
787787
DC = I->getParent()->getParent();
788788
continue;
789789
} else {
790-
assert(isa<TopLevelCodeDecl>(DC) || isa<Initializer>(DC));
790+
assert(isa<TopLevelCodeDecl>(DC) || isa<Initializer>(DC) ||
791+
isa<TypeAliasDecl>(DC));
791792
if (!isCascadingUse.hasValue())
792793
isCascadingUse = DC->isCascadingContextForLookup(false);
793794
}

lib/IDE/CodeCompletion.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4069,9 +4069,9 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
40694069

40704070
void addAccessControl(const ValueDecl *VD,
40714071
CodeCompletionResultBuilder &Builder) {
4072-
assert(CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext());
4072+
assert(CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext());
40734073
auto AccessibilityOfContext =
4074-
CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext()
4074+
CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext()
40754075
->getFormalAccess();
40764076
auto Access = std::min(VD->getFormalAccess(), AccessibilityOfContext);
40774077
// Only emit 'public', not needed otherwise.
@@ -4309,7 +4309,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
43094309
}
43104310

43114311
void getOverrideCompletions(SourceLoc Loc) {
4312-
if (!CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext())
4312+
if (!CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext())
43134313
return;
43144314

43154315
Type CurrTy = CurrDeclContext->getDeclaredTypeInContext();

lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3827,7 +3827,6 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage,
38273827
SmallVectorImpl<Decl *> &decls) {
38283828
auto flagInvalidAccessor = [&](FuncDecl *&func) {
38293829
if (func) {
3830-
func->setInterfaceType(ErrorType::get(P.Context));
38313830
func->setInvalid();
38323831
}
38333832
};

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ namespace {
704704
if (!isa<ConstructorDecl>(fn))
705705
return false;
706706
auto *parent =
707-
fn->getParent()->getAsGenericTypeOrGenericTypeExtensionContext();
707+
fn->getParent()->getAsNominalTypeOrNominalTypeExtensionContext();
708708
return parent && (isa<ClassDecl>(parent) || isa<ProtocolDecl>(parent));
709709
}
710710

lib/Sema/CSDiag.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4671,8 +4671,8 @@ static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
46714671
};
46724672

46734673
auto getBaseName = [](DeclContext *context) -> DeclName {
4674-
if (context->isTypeContext()) {
4675-
auto generic = context->getAsGenericTypeOrGenericTypeExtensionContext();
4674+
if (auto generic =
4675+
context->getAsNominalTypeOrNominalTypeExtensionContext()) {
46764676
return generic->getName();
46774677
} else if (context->isModuleScopeContext())
46784678
return context->getParentModule()->getName();

lib/Sema/GenericTypeResolver.h

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -159,35 +159,6 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
159159
virtual void recordParamType(ParamDecl *decl, Type ty);
160160
};
161161

162-
/// Generic type resolver that maps any generic type parameter type that
163-
/// has an underlying archetype to its corresponding archetype.
164-
///
165-
/// This generic type resolver replaces generic type parameter types that
166-
/// have archetypes with their archetypes, and leaves all other generic
167-
/// type parameter types unchanged. It is used for the initial type-checks of
168-
/// generic functions (and other generic declarations).
169-
///
170-
/// FIXME: This is not a long-term solution.
171-
class PartialGenericTypeToArchetypeResolver : public GenericTypeResolver {
172-
public:
173-
virtual Type resolveGenericTypeParamType(GenericTypeParamType *gp);
174-
175-
virtual Type resolveDependentMemberType(Type baseTy,
176-
DeclContext *DC,
177-
SourceRange baseRange,
178-
ComponentIdentTypeRepr *ref);
179-
180-
virtual Type resolveSelfAssociatedType(Type selfTy,
181-
DeclContext *DC,
182-
AssociatedTypeDecl *assocType);
183-
184-
virtual Type resolveTypeOfContext(DeclContext *dc, bool wantSelf=false);
185-
186-
virtual Type resolveTypeOfDecl(TypeDecl *decl);
187-
188-
virtual void recordParamType(ParamDecl *decl, Type ty);
189-
};
190-
191162
/// Generic type resolver that performs complete resolution of dependent
192163
/// types based on a given archetype builder.
193164
///

lib/Sema/ITCDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ void IterativeTypeChecker::processResolveInheritedClauseEntry(
103103

104104
// Validate the type of this inherited clause entry.
105105
// FIXME: Recursion into existing type checker.
106-
PartialGenericTypeToArchetypeResolver resolver;
106+
GenericTypeToArchetypeResolver resolver(dc);
107107
if (TC.validateType(*inherited, dc, options, &resolver)) {
108108
inherited->setInvalidType(getASTContext());
109109
}
@@ -314,9 +314,10 @@ void IterativeTypeChecker::processResolveTypeDecl(
314314

315315
// Note: recursion into old type checker is okay when passing in an
316316
// unsatisfied-dependency callback.
317+
GenericTypeToArchetypeResolver resolver(typeAliasDecl);
317318
if (TC.validateType(typeAliasDecl->getUnderlyingTypeLoc(),
318319
typeAliasDecl->getDeclContext(),
319-
options, nullptr, &unsatisfiedDependency)) {
320+
options, &resolver, &unsatisfiedDependency)) {
320321
typeAliasDecl->setInvalid();
321322
typeAliasDecl->setInterfaceType(ErrorType::get(getASTContext()));
322323
typeAliasDecl->getUnderlyingTypeLoc().setInvalidType(getASTContext());

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -937,8 +937,7 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) {
937937
options |= TR_InExpression;
938938
bool hadParameterError = false;
939939

940-
GenericTypeToArchetypeResolver resolver(
941-
closure->getGenericEnvironmentOfContext());
940+
GenericTypeToArchetypeResolver resolver(closure);
942941

943942
if (TC.typeCheckParameterList(PL, DC, options, resolver)) {
944943
closure->setType(ErrorType::get(TC.Context));

0 commit comments

Comments
 (0)