Skip to content

Commit 07780bd

Browse files
committed
AST: Don't call hasType()/getType()/setType() on AbstractTypeParamDecls
1 parent 2d83a79 commit 07780bd

File tree

8 files changed

+53
-62
lines changed

8 files changed

+53
-62
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,22 +2004,8 @@ class ValueDecl : public Decl {
20042004
SourceLoc getNameLoc() const { return NameLoc; }
20052005
SourceLoc getLoc() const { return NameLoc; }
20062006

2007-
bool hasType() const {
2008-
assert(!isa<AbstractFunctionDecl>(this) &&
2009-
!isa<EnumElementDecl>(this) &&
2010-
!isa<SubscriptDecl>(this) &&
2011-
"functions and enum case constructors only have an interface type");
2012-
return !TypeAndAccess.getPointer().isNull();
2013-
}
2014-
2015-
Type getType() const {
2016-
assert(!isa<AbstractFunctionDecl>(this) &&
2017-
!isa<EnumElementDecl>(this) &&
2018-
!isa<SubscriptDecl>(this) &&
2019-
"functions and enum case constructors only have an interface type");
2020-
assert(hasType() && "declaration has no type set yet");
2021-
return TypeAndAccess.getPointer();
2022-
}
2007+
bool hasType() const;
2008+
Type getType() const;
20232009

20242010
/// Set the type of this declaration for the first time.
20252011
void setType(Type T);

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ namespace {
516516

517517
if (!isa<AbstractFunctionDecl>(VD) &&
518518
!isa<EnumElementDecl>(VD) &&
519-
!isa<SubscriptDecl>(VD)) {
519+
!isa<SubscriptDecl>(VD) &&
520+
!isa<AbstractTypeParamDecl>(VD)) {
520521
OS << " type='";
521522
if (VD->hasType())
522523
VD->getType().print(OS);

lib/AST/ArchetypeBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,8 +1453,8 @@ bool ArchetypeBuilder::addAbstractTypeParamRequirements(
14531453
};
14541454

14551455
if (isa<AssociatedTypeDecl>(decl) &&
1456-
decl->hasType() &&
1457-
decl->getType()->is<ErrorType>())
1456+
decl->hasInterfaceType() &&
1457+
decl->getInterfaceType()->is<ErrorType>())
14581458
return false;
14591459

14601460
// If this is an associated type that already has an archetype assigned,

lib/AST/Decl.cpp

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,25 @@ ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const {
16441644
return NTD->getSatisfiedProtocolRequirementsForMember(this, Sorted);
16451645
}
16461646

1647+
bool ValueDecl::hasType() const {
1648+
assert(!isa<AbstractFunctionDecl>(this) &&
1649+
!isa<EnumElementDecl>(this) &&
1650+
!isa<SubscriptDecl>(this) &&
1651+
!isa<AbstractTypeParamDecl>(this) &&
1652+
"functions and enum case constructors only have an interface type");
1653+
return !TypeAndAccess.getPointer().isNull();
1654+
}
1655+
1656+
Type ValueDecl::getType() const {
1657+
assert(!isa<AbstractFunctionDecl>(this) &&
1658+
!isa<EnumElementDecl>(this) &&
1659+
!isa<SubscriptDecl>(this) &&
1660+
!isa<AbstractTypeParamDecl>(this) &&
1661+
"functions and enum case constructors only have an interface type");
1662+
assert(hasType() && "declaration has no type set yet");
1663+
return TypeAndAccess.getPointer();
1664+
}
1665+
16471666
void ValueDecl::setType(Type T) {
16481667
assert(!hasType() && "changing type of declaration");
16491668
overwriteType(T);
@@ -1653,6 +1672,7 @@ void ValueDecl::overwriteType(Type T) {
16531672
assert(!isa<AbstractFunctionDecl>(this) &&
16541673
!isa<EnumElementDecl>(this) &&
16551674
!isa<SubscriptDecl>(this) &&
1675+
!isa<AbstractTypeParamDecl>(this) &&
16561676
"functions and enum case constructors only have an interface type");
16571677

16581678
TypeAndAccess.setPointer(T);
@@ -1661,13 +1681,6 @@ void ValueDecl::overwriteType(Type T) {
16611681
}
16621682

16631683
bool ValueDecl::hasInterfaceType() const {
1664-
// getInterfaceType() always returns something for associated types.
1665-
if (isa<AssociatedTypeDecl>(this)) {
1666-
auto proto = cast<ProtocolDecl>(getDeclContext());
1667-
auto selfTy = proto->getSelfInterfaceType();
1668-
return !!selfTy;
1669-
}
1670-
16711684
// getInterfaceType() returns the contextual type for ParamDecls which
16721685
// don't have an explicit interface type.
16731686
if (isa<ParamDecl>(this))
@@ -1680,19 +1693,6 @@ Type ValueDecl::getInterfaceType() const {
16801693
if (InterfaceTy)
16811694
return InterfaceTy;
16821695

1683-
if (auto assocType = dyn_cast<AssociatedTypeDecl>(this)) {
1684-
auto proto = cast<ProtocolDecl>(getDeclContext());
1685-
auto selfTy = proto->getSelfInterfaceType();
1686-
if (!selfTy)
1687-
return Type();
1688-
auto &ctx = getASTContext();
1689-
InterfaceTy = DependentMemberType::get(
1690-
selfTy,
1691-
const_cast<AssociatedTypeDecl *>(assocType));
1692-
InterfaceTy = MetatypeType::get(InterfaceTy, ctx);
1693-
return InterfaceTy;
1694-
}
1695-
16961696
if (!hasType())
16971697
return Type();
16981698

@@ -2257,7 +2257,6 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
22572257
{
22582258
auto &ctx = dc->getASTContext();
22592259
auto type = new (ctx, AllocationArena::Permanent) GenericTypeParamType(this);
2260-
setType(MetatypeType::get(type, ctx));
22612260
setInterfaceType(MetatypeType::get(type, ctx));
22622261
}
22632262

@@ -2301,8 +2300,12 @@ AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
23012300

23022301
void AssociatedTypeDecl::computeType() {
23032302
auto &ctx = getASTContext();
2304-
auto type = new (ctx, AllocationArena::Permanent) AssociatedTypeType(this);
2305-
setType(MetatypeType::get(type, ctx));
2303+
auto proto = cast<ProtocolDecl>(getDeclContext());
2304+
auto selfTy = proto->getSelfInterfaceType();
2305+
if (!selfTy)
2306+
selfTy = ErrorType::get(ctx);
2307+
auto interfaceTy = DependentMemberType::get(selfTy, this);
2308+
setInterfaceType(MetatypeType::get(interfaceTy, ctx));
23062309
}
23072310

23082311
TypeLoc &AssociatedTypeDecl::getDefaultDefinitionLoc() {

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,11 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
319319
// If this is a decl that we have an lvalue for, produce and return it.
320320
ValueDecl *decl = declRef.getDecl();
321321

322-
if (!ncRefType) ncRefType = decl->getType();
322+
if (!ncRefType) {
323+
ncRefType = ArchetypeBuilder::mapTypeIntoContext(
324+
decl->getInnermostDeclContext(),
325+
decl->getInterfaceType());
326+
}
323327
CanType refType = ncRefType->getCanonicalType();
324328

325329
auto getUnmanagedRValue = [&](SILValue value) -> RValue {
@@ -335,7 +339,7 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
335339

336340
// If this is a reference to a type, produce a metatype.
337341
if (isa<TypeDecl>(decl)) {
338-
assert(decl->getType()->is<MetatypeType>() &&
342+
assert(refType->is<MetatypeType>() &&
339343
"type declref does not have metatype type?!");
340344
return getUnmanagedRValue(B.createMetatype(loc, getLoweredType(refType)));
341345
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,8 @@ static void checkRedeclaration(TypeChecker &tc, ValueDecl *current) {
945945
current->setInvalid();
946946
if (!isa<AbstractFunctionDecl>(current) &&
947947
!isa<EnumElementDecl>(current) &&
948-
!isa<SubscriptDecl>(current))
948+
!isa<SubscriptDecl>(current) &&
949+
!isa<AbstractTypeParamDecl>(current))
949950
if (current->hasType())
950951
current->overwriteType(ErrorType::get(tc.Context));
951952
if (current->hasInterfaceType())
@@ -6879,12 +6880,12 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
68796880

68806881
DeclContext *DC = typeParam->getDeclContext();
68816882

6883+
if (assocType && !assocType->hasInterfaceType())
6884+
assocType->computeType();
6885+
68826886
if (!resolveTypeParams || DC->isValidGenericContext()) {
68836887
if (assocType) {
68846888
DeclChecker(*this, false, false).visitAssociatedTypeDecl(assocType);
6885-
6886-
if (!assocType->hasType())
6887-
assocType->computeType();
68886889
}
68896890

68906891
break;
@@ -6903,9 +6904,6 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
69036904
case DeclContextKind::GenericTypeDecl: {
69046905
auto nominal = cast<GenericTypeDecl>(DC);
69056906
validateDecl(nominal);
6906-
if (auto assocType = dyn_cast<AssociatedTypeDecl>(typeParam))
6907-
if (!assocType->hasType())
6908-
assocType->computeType();
69096907
if (!typeParam->hasAccessibility())
69106908
typeParam->setAccessibility(std::max(nominal->getFormalAccess(),
69116909
Accessibility::Internal));
@@ -6925,9 +6923,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
69256923
typeCheckDecl(extension, true);
69266924
auto fn = cast<AbstractFunctionDecl>(DC);
69276925
typeCheckDecl(fn, true);
6928-
if (auto assocType = dyn_cast<AssociatedTypeDecl>(typeParam))
6929-
if (!assocType->hasType())
6930-
assocType->computeType();
6926+
assert(!assocType && "Associated type inside function?");
69316927
if (!typeParam->hasAccessibility())
69326928
typeParam->setAccessibility(std::max(fn->getFormalAccess(),
69336929
Accessibility::Internal));
@@ -7049,7 +7045,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
70497045
// appropriate archetype.
70507046
for (auto member : proto->getMembers()) {
70517047
if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
7052-
if (!assocType->hasType())
7048+
if (!assocType->hasInterfaceType())
70537049
assocType->computeType();
70547050
}
70557051
}

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
331331

332332
// FIXME: This should happen before we attempt shadowing checks.
333333
validateDecl(typeDecl);
334-
if (!typeDecl->hasType()) // FIXME: recursion-breaking hack
334+
if (!typeDecl->hasInterfaceType()) // FIXME: recursion-breaking hack
335335
continue;
336336

337337
// If we're looking up a member of a protocol, we must take special care.

lib/Sema/TypeCheckType.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ static Type resolveTypeDecl(TypeChecker &TC, TypeDecl *typeDecl, SourceLoc loc,
661661
TC.validateDecl(typeDecl);
662662

663663
// FIXME: More principled handling of circularity.
664-
if (!isa<AssociatedTypeDecl>(typeDecl) && !typeDecl->hasType())
664+
if (!typeDecl->hasInterfaceType())
665665
return ErrorType::get(TC.Context);
666666
}
667667

@@ -1107,6 +1107,7 @@ static Type resolveNestedIdentTypeComponent(
11071107
// Phase 2: If a declaration has already been bound, use it.
11081108
if (ValueDecl *decl = comp->getBoundDecl()) {
11091109
auto *typeDecl = cast<TypeDecl>(decl);
1110+
auto *assocType = dyn_cast<AssociatedTypeDecl>(typeDecl);
11101111

11111112
Type memberType;
11121113

@@ -1126,18 +1127,18 @@ static Type resolveNestedIdentTypeComponent(
11261127
return memberType;
11271128
}
11281129

1129-
if (isa<AssociatedTypeDecl>(typeDecl) &&
1130-
!parentTy->is<ArchetypeType>()) {
1131-
assert(!parentTy->isExistentialType());
1130+
if (assocType && !assocType->hasInterfaceType())
1131+
assocType->computeType();
11321132

1133-
auto assocType = cast<AssociatedTypeDecl>(typeDecl);
1133+
if (assocType && !parentTy->is<ArchetypeType>()) {
1134+
assert(!parentTy->isExistentialType());
11341135

11351136
// Find the conformance and dig out the type witness.
11361137
ConformanceCheckOptions conformanceOptions;
11371138
if (options.contains(TR_InExpression))
11381139
conformanceOptions |= ConformanceCheckFlags::InExpression;
11391140

1140-
auto *protocol = cast<ProtocolDecl>(assocType->getDeclContext());
1141+
auto *protocol = assocType->getProtocol();
11411142
auto conformance = TC.conformsToProtocol(parentTy, protocol, DC,
11421143
conformanceOptions);
11431144
if (!conformance || conformance->isAbstract()) {

0 commit comments

Comments
 (0)