Skip to content

Commit 2c6b9f7

Browse files
committed
AST: Change TypeAliasDecls to store an interface type as their underlying type
- TypeAliasDecl::getAliasType() is gone. Now, getDeclaredInterfaceType() always returns the NameAliasType. - NameAliasTypes now always desugar to the underlying type as an interface type. - The NameAliasType of a generic type alias no longer desugars to an UnboundGenericType; call TypeAliasDecl::getUnboundGenericType() if you want that. - The "lazy mapTypeOutOfContext()" hack for deserialized TypeAliasDecls is gone. - The process of constructing a synthesized TypeAliasDecl is much simpler now; instead of calling computeType(), setInterfaceType() and then setting the recursive properties in the right order, just call setUnderlyingType(), passing it either an interface type or a contextual type. In particular, many places weren't setting the recursive properties, such as the ClangImporter and deserialization. This meant that queries such as hasArchetype() or hasTypeParameter() would return incorrect results on NameAliasTypes, which caused various subtle problems. - Finally, add some more tests for generic typealiases, most of which fail because they're still pretty broken.
1 parent 757f253 commit 2c6b9f7

39 files changed

+392
-285
lines changed

include/swift/AST/Decl.h

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ namespace swift {
7272
class TypeAliasDecl;
7373
class Stmt;
7474
class SubscriptDecl;
75+
class UnboundGenericType;
7576
class ValueDecl;
7677
class VarDecl;
7778

@@ -413,9 +414,10 @@ class alignas(1 << DeclAlignInBits) Decl {
413414
friend class TypeAliasDecl;
414415
unsigned : NumGenericTypeDeclBits;
415416

416-
/// Whether the underlying type is an interface type that will be lazily
417-
/// resolved to a context type.
418-
unsigned HasInterfaceUnderlyingType : 1;
417+
/// Whether we have completed validation of the typealias.
418+
/// This is necessary because unlike other declarations, a
419+
/// typealias will not get an interface type right away.
420+
unsigned HasCompletedValidation : 1;
419421
};
420422
enum { NumTypeAliasDeclBits = NumGenericTypeDeclBits + 1 };
421423
static_assert(NumTypeAliasDeclBits <= 32, "fits in an unsigned");
@@ -2391,60 +2393,38 @@ class GenericTypeDecl : public TypeDecl, public DeclContext {
23912393
/// TypeAliasDecl's always have 'MetatypeType' type.
23922394
///
23932395
class TypeAliasDecl : public GenericTypeDecl {
2394-
/// The type that represents this (sugared) name alias.
2395-
mutable NameAliasType *AliasTy;
2396-
23972396
SourceLoc TypeAliasLoc; // The location of the 'typealias' keyword
2398-
mutable TypeLoc UnderlyingTy;
2399-
2400-
Type computeUnderlyingContextType() const;
2397+
TypeLoc UnderlyingTy;
24012398

24022399
public:
24032400
TypeAliasDecl(SourceLoc TypeAliasLoc, Identifier Name,
2404-
SourceLoc NameLoc, TypeLoc UnderlyingTy,
2405-
GenericParamList *GenericParams, DeclContext *DC);
2401+
SourceLoc NameLoc, GenericParamList *GenericParams,
2402+
DeclContext *DC);
24062403

24072404
SourceLoc getStartLoc() const { return TypeAliasLoc; }
24082405
SourceRange getSourceRange() const;
24092406

2410-
/// getUnderlyingType - Returns the underlying type, which is
2411-
/// assumed to have been set.
2412-
Type getUnderlyingType() const {
2413-
if (TypeAliasDeclBits.HasInterfaceUnderlyingType)
2414-
return computeUnderlyingContextType();
2415-
2416-
assert(!UnderlyingTy.getType().isNull() &&
2417-
"getting invalid underlying type");
2418-
return UnderlyingTy.getType();
2419-
}
2420-
2421-
/// computeType - Compute the type (and declared type) of this type alias;
2422-
/// can only be called after the alias type has been resolved.
2423-
void computeType();
2424-
2425-
/// \brief Determine whether this type alias has an underlying type.
2426-
bool hasUnderlyingType() const {
2427-
return !UnderlyingTy.getType().isNull();
2428-
}
2429-
24302407
TypeLoc &getUnderlyingTypeLoc() {
2431-
if (TypeAliasDeclBits.HasInterfaceUnderlyingType)
2432-
(void)computeUnderlyingContextType();
2433-
24342408
return UnderlyingTy;
24352409
}
24362410
const TypeLoc &getUnderlyingTypeLoc() const {
2437-
if (TypeAliasDeclBits.HasInterfaceUnderlyingType)
2438-
(void)computeUnderlyingContextType();
2439-
24402411
return UnderlyingTy;
24412412
}
24422413

2443-
/// Set the underlying type after deserialization.
2444-
void setDeserializedUnderlyingType(Type type);
2414+
/// Set the underlying type, for deserialization and synthesized
2415+
/// aliases.
2416+
void setUnderlyingType(Type type);
2417+
2418+
bool hasCompletedValidation() const {
2419+
return TypeAliasDeclBits.HasCompletedValidation;
2420+
}
2421+
2422+
void setHasCompletedValidation() {
2423+
TypeAliasDeclBits.HasCompletedValidation = 1;
2424+
}
24452425

2446-
/// getAliasType - Return the sugared version of this decl as a Type.
2447-
NameAliasType *getAliasType() const { return AliasTy; }
2426+
/// For generic typealiases, return the unbound generic type.
2427+
UnboundGenericType *getUnboundGenericType() const;
24482428

24492429
static bool classof(const Decl *D) {
24502430
return D->getKind() == DeclKind::TypeAlias;

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3661,7 +3661,7 @@ static NominalTypeDecl *findUnderlyingTypeInModule(ASTContext &ctx,
36613661
if (auto typealias = dyn_cast<TypeAliasDecl>(result)) {
36623662
if (auto resolver = ctx.getLazyResolver())
36633663
resolver->resolveDeclSignature(typealias);
3664-
return typealias->getUnderlyingType()->getAnyNominal();
3664+
return typealias->getDeclaredInterfaceType()->getAnyNominal();
36653665
}
36663666
}
36673667

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@ namespace {
460460
void visitTypeAliasDecl(TypeAliasDecl *TAD) {
461461
printCommon(TAD, "typealias");
462462
OS << " type='";
463-
if (TAD->hasUnderlyingType())
464-
OS << TAD->getUnderlyingType().getString();
463+
if (TAD->getUnderlyingTypeLoc().getType())
464+
OS << TAD->getUnderlyingTypeLoc().getType().getString();
465465
else
466466
OS << "<<<unresolved>>>";
467467
printInherited(TAD->getInherited());

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ void ASTMangler::appendType(Type type) {
454454
TypeAliasDecl *decl = NameAliasTy->getDecl();
455455
if (decl->getModuleContext() == decl->getASTContext().TheBuiltinModule) {
456456
// It's not possible to mangle the context of the builtin module.
457-
return appendType(decl->getUnderlyingType());
457+
return appendType(decl->getDeclaredInterfaceType());
458458
}
459459

460460
// For the DWARF output we want to mangle the type alias + context,

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,9 +2141,8 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
21412141
printGenericSignature(genericSig, PrintParams | InnermostOnly);
21422142
});
21432143
bool ShouldPrint = true;
2144-
Type Ty;
2145-
if (decl->hasUnderlyingType())
2146-
Ty = decl->getUnderlyingType();
2144+
Type Ty = decl->getUnderlyingTypeLoc().getType();
2145+
21472146
// If the underlying type is private, don't print it.
21482147
if (Options.SkipPrivateStdlibDecls && Ty && Ty.isPrivateStdlibType())
21492148
ShouldPrint = false;

lib/AST/ArchetypeBuilder.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,19 +413,14 @@ auto ArchetypeBuilder::PotentialArchetype::getNestedType(
413413
// Resolve this nested type to this type alias.
414414
pa = new PotentialArchetype(this, alias);
415415

416-
if (!alias->hasUnderlyingType())
416+
if (!alias->hasInterfaceType())
417417
builder.getLazyResolver()->resolveDeclSignature(alias);
418-
if (!alias->hasUnderlyingType())
418+
if (!alias->hasInterfaceType())
419419
continue;
420420

421-
auto type = alias->getUnderlyingType();
421+
auto type = alias->getDeclaredInterfaceType();
422422
SmallVector<Identifier, 4> identifiers;
423423

424-
// Map the type out of its context.
425-
if (auto genericEnv = alias->getGenericEnvironmentOfContext()) {
426-
type = genericEnv->mapTypeOutOfContext(type);
427-
}
428-
429424
if (auto existingPA = builder.resolveArchetype(type)) {
430425
builder.addSameTypeRequirementBetweenArchetypes(pa, existingPA,
431426
redundantSource);

lib/AST/Decl.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,8 @@ ImportKind ImportDecl::getBestImportKind(const ValueDecl *VD) {
622622
return ImportKind::Struct;
623623

624624
case DeclKind::TypeAlias: {
625-
Type underlyingTy = cast<TypeAliasDecl>(VD)->getUnderlyingType();
626-
return getBestImportKind(underlyingTy->getAnyNominal());
625+
Type type = cast<TypeAliasDecl>(VD)->getDeclaredInterfaceType();
626+
return getBestImportKind(type->getAnyNominal());
627627
}
628628

629629
case DeclKind::Func:
@@ -1907,7 +1907,7 @@ Type TypeDecl::getDeclaredInterfaceType() const {
19071907
return NTD->getDeclaredInterfaceType();
19081908

19091909
Type interfaceType = getInterfaceType();
1910-
if (interfaceType.isNull() || interfaceType->hasError())
1910+
if (interfaceType.isNull() || interfaceType->is<ErrorType>())
19111911
return interfaceType;
19121912

19131913
if (isa<ModuleDecl>(this))
@@ -2191,17 +2191,11 @@ void GenericTypeDecl::setLazyGenericEnvironment(LazyMemberLoader *lazyLoader,
21912191
}
21922192

21932193
TypeAliasDecl::TypeAliasDecl(SourceLoc TypeAliasLoc, Identifier Name,
2194-
SourceLoc NameLoc, TypeLoc UnderlyingTy,
2195-
GenericParamList *GenericParams, DeclContext *DC)
2194+
SourceLoc NameLoc, GenericParamList *GenericParams,
2195+
DeclContext *DC)
21962196
: GenericTypeDecl(DeclKind::TypeAlias, DC, Name, NameLoc, {}, GenericParams),
2197-
AliasTy(nullptr), TypeAliasLoc(TypeAliasLoc), UnderlyingTy(UnderlyingTy) {
2198-
TypeAliasDeclBits.HasInterfaceUnderlyingType = false;
2199-
}
2200-
2201-
void TypeAliasDecl::computeType() {
2202-
ASTContext &Ctx = getASTContext();
2203-
assert(!AliasTy && "already called computeType()");
2204-
AliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2197+
TypeAliasLoc(TypeAliasLoc) {
2198+
TypeAliasDeclBits.HasCompletedValidation = false;
22052199
}
22062200

22072201
SourceRange TypeAliasDecl::getSourceRange() const {
@@ -2210,6 +2204,33 @@ SourceRange TypeAliasDecl::getSourceRange() const {
22102204
return { TypeAliasLoc, getNameLoc() };
22112205
}
22122206

2207+
void TypeAliasDecl::setUnderlyingType(Type underlying) {
2208+
setHasCompletedValidation();
2209+
2210+
// lldb creates global typealiases containing archetypes
2211+
// sometimes...
2212+
if (underlying->hasArchetype() && isGenericContext())
2213+
underlying = mapTypeOutOfContext(underlying);
2214+
UnderlyingTy.setType(underlying);
2215+
2216+
// Create a NameAliasType which will resolve to the underlying type.
2217+
ASTContext &Ctx = getASTContext();
2218+
auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2219+
aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
2220+
->getRecursiveProperties());
2221+
2222+
// Set the interface type of this declaration.
2223+
setInterfaceType(MetatypeType::get(aliasTy, Ctx));
2224+
}
2225+
2226+
UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
2227+
assert(getGenericParams());
2228+
return UnboundGenericType::get(
2229+
const_cast<TypeAliasDecl *>(this),
2230+
getDeclContext()->getDeclaredTypeOfContext(),
2231+
getASTContext());
2232+
}
2233+
22132234
Type AbstractTypeParamDecl::getSuperclass() const {
22142235
auto *dc = getDeclContext();
22152236
if (!dc->isValidGenericContext())
@@ -2223,22 +2244,6 @@ Type AbstractTypeParamDecl::getSuperclass() const {
22232244
return nullptr;
22242245
}
22252246

2226-
Type TypeAliasDecl::computeUnderlyingContextType() const {
2227-
Type type = UnderlyingTy.getType();
2228-
if (auto genericEnv = getGenericEnvironmentOfContext()) {
2229-
type = genericEnv->mapTypeIntoContext(getParentModule(), type);
2230-
UnderlyingTy.setType(type);
2231-
}
2232-
2233-
return type;
2234-
}
2235-
2236-
void TypeAliasDecl::setDeserializedUnderlyingType(Type underlying) {
2237-
UnderlyingTy.setType(underlying);
2238-
if (underlying->hasTypeParameter())
2239-
TypeAliasDeclBits.HasInterfaceUnderlyingType = true;
2240-
}
2241-
22422247
ArrayRef<ProtocolDecl *>
22432248
AbstractTypeParamDecl::getConformingProtocols() const {
22442249
auto *dc = getDeclContext();

lib/AST/Mangle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ void Mangler::mangleType(Type type, unsigned uncurryLevel) {
854854
TypeAliasDecl *decl = NameAliasTy->getDecl();
855855
if (decl->getModuleContext() == decl->getASTContext().TheBuiltinModule) {
856856
// It's not possible to mangle the context of the builtin module.
857-
return mangleType(decl->getUnderlyingType(), uncurryLevel);
857+
return mangleType(NameAliasTy->getSinglyDesugaredType(), uncurryLevel);
858858
}
859859

860860
Buffer << "a";

lib/AST/Module.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,9 @@ void BuiltinUnit::LookupCache::lookupValue(
8080
if (!Entry) {
8181
if (Type Ty = getBuiltinType(Ctx, Name.str())) {
8282
auto *TAD = new (Ctx) TypeAliasDecl(SourceLoc(), Name, SourceLoc(),
83-
TypeLoc::withoutLoc(Ty),
8483
/*genericparams*/nullptr,
8584
const_cast<BuiltinUnit*>(&M));
86-
TAD->computeType();
87-
TAD->setInterfaceType(MetatypeType::get(TAD->getAliasType(), Ctx));
85+
TAD->setUnderlyingType(Ty);
8886
TAD->setAccessibility(Accessibility::Public);
8987
Entry = TAD;
9088
}

lib/AST/Type.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,15 +1308,7 @@ TypeBase *ParenType::getSinglyDesugaredType() {
13081308
}
13091309

13101310
TypeBase *NameAliasType::getSinglyDesugaredType() {
1311-
auto *TAD = getDecl();
1312-
1313-
// The type for a generic TypeAliasDecl is an UnboundGenericType.
1314-
if (TAD->getGenericParams())
1315-
return UnboundGenericType::get(TAD,
1316-
TAD->getDeclContext()->getDeclaredTypeInContext(),
1317-
TAD->getASTContext());
1318-
1319-
return getDecl()->getUnderlyingType().getPointer();
1311+
return getDecl()->getUnderlyingTypeLoc().getType().getPointer();
13201312
}
13211313

13221314
TypeBase *SyntaxSugarType::getSinglyDesugaredType() {
@@ -3436,15 +3428,15 @@ case TypeKind::Id:
34363428

34373429
case TypeKind::NameAlias: {
34383430
auto alias = cast<NameAliasType>(base);
3439-
auto underlyingTy = alias->getDecl()->getUnderlyingType().transform(fn);
3440-
if (!underlyingTy)
3431+
auto underlyingTy = Type(alias->getSinglyDesugaredType());
3432+
auto transformedTy = underlyingTy.transform(fn);
3433+
if (!transformedTy)
34413434
return Type();
34423435

3443-
if (underlyingTy.getPointer() ==
3444-
alias->getDecl()->getUnderlyingType().getPointer())
3436+
if (transformedTy.getPointer() == underlyingTy.getPointer())
34453437
return *this;
34463438

3447-
return underlyingTy;
3439+
return transformedTy;
34483440
}
34493441

34503442
case TypeKind::Paren: {

0 commit comments

Comments
 (0)