Skip to content

Commit 2ff9061

Browse files
authored
Merge pull request #6321 from slavapestov/typealias-underlying-interface-type
Change the underlying type of TypeAliasDecls to an interface type
2 parents 4c06e45 + 2c6b9f7 commit 2ff9061

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+598
-473
lines changed

include/swift/AST/Decl.h

Lines changed: 25 additions & 50 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;
@@ -4164,10 +4144,7 @@ class VarDecl : public AbstractStorageDecl {
41644144
/// This is the type specified, including location information.
41654145
TypeLoc typeLoc;
41664146

4167-
mutable Type typeInContext;
4168-
4169-
/// Compute the type in context from the interface type.
4170-
Type computeTypeInContextSlow() const;
4147+
Type typeInContext;
41714148

41724149
public:
41734150
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
@@ -4190,15 +4167,13 @@ class VarDecl : public AbstractStorageDecl {
41904167
bool hasType() const {
41914168
// We have a type if either the type has been computed already or if
41924169
// this is a deserialized declaration with an interface type.
4193-
return typeInContext ||
4194-
(hasInterfaceType() && !getDeclContext()->getParentSourceFile());
4170+
return !typeInContext.isNull();
41954171
}
41964172

41974173
/// Get the type of the variable within its context. If the context is generic,
41984174
/// this will use archetypes.
41994175
Type getType() const {
4200-
if (!typeInContext)
4201-
return computeTypeInContextSlow();
4176+
assert(!typeInContext.isNull() && "no contextual type set yet");
42024177
return typeInContext;
42034178
}
42044179

@@ -4414,7 +4389,7 @@ class ParamDecl : public VarDecl {
44144389
/// type wrapping it.
44154390
Type getVarargBaseTy() const {
44164391
assert(isVariadic());
4417-
return getVarargBaseTy(getType());
4392+
return getVarargBaseTy(getInterfaceType());
44184393
}
44194394

44204395
SourceRange getSourceRange() const;

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: 6 additions & 11 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;
@@ -2338,11 +2337,11 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
23382337
[&]{
23392338
Printer.printName(decl->getName());
23402339
});
2341-
if (decl->hasType()) {
2340+
if (decl->hasInterfaceType()) {
23422341
Printer << ": ";
23432342
auto tyLoc = decl->getTypeLoc();
23442343
if (!tyLoc.getTypeRepr())
2345-
tyLoc = TypeLoc::withoutLoc(decl->getType());
2344+
tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());
23462345
printTypeLoc(tyLoc);
23472346
}
23482347

@@ -2395,12 +2394,8 @@ void PrintAST::printOneParameter(const ParamDecl *param,
23952394

23962395
printArgName();
23972396

2398-
if (!TheTypeLoc.getTypeRepr() && param->hasType()) {
2399-
// FIXME: ParamDecls should have interface types instead
2400-
auto *DC = Current->getInnermostDeclContext();
2401-
auto type = ArchetypeBuilder::mapTypeOutOfContext(DC, param->getType());
2402-
TheTypeLoc = TypeLoc::withoutLoc(type);
2403-
}
2397+
if (!TheTypeLoc.getTypeRepr() && param->hasInterfaceType())
2398+
TheTypeLoc = TypeLoc::withoutLoc(param->getInterfaceType());
24042399

24052400
// If the parameter is variadic, we will print the "..." after it, but we have
24062401
// to strip off the added array type.

lib/AST/ASTVerifier.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,15 +1704,15 @@ struct ASTNodeBase {};
17041704

17051705
// Variables must have materializable type, unless they are parameters,
17061706
// in which case they must either have l-value type or be anonymous.
1707-
if (!var->getType()->isMaterializable()) {
1707+
if (!var->getInterfaceType()->isMaterializable()) {
17081708
if (!isa<ParamDecl>(var)) {
17091709
Out << "Non-parameter VarDecl has non-materializable type: ";
17101710
var->getType().print(Out);
17111711
Out << "\n";
17121712
abort();
17131713
}
17141714

1715-
if (!var->getType()->is<InOutType>() && var->hasName()) {
1715+
if (!var->getInterfaceType()->is<InOutType>() && var->hasName()) {
17161716
Out << "ParamDecl may only have non-materializable tuple type "
17171717
"when it is anonymous: ";
17181718
var->getType().print(Out);
@@ -1724,15 +1724,15 @@ struct ASTNodeBase {};
17241724
// The fact that this is *directly* be a reference storage type
17251725
// cuts the code down quite a bit in getTypeOfReference.
17261726
if (var->getAttrs().hasAttribute<OwnershipAttr>() !=
1727-
isa<ReferenceStorageType>(var->getType().getPointer())) {
1727+
isa<ReferenceStorageType>(var->getInterfaceType().getPointer())) {
17281728
if (var->getAttrs().hasAttribute<OwnershipAttr>()) {
17291729
Out << "VarDecl has an ownership attribute, but its type"
17301730
" is not a ReferenceStorageType: ";
17311731
} else {
17321732
Out << "VarDecl has no ownership attribute, but its type"
17331733
" is a ReferenceStorageType: ";
17341734
}
1735-
var->getType().print(Out);
1735+
var->getInterfaceType().print(Out);
17361736
abort();
17371737
}
17381738

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/Builtins.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ getBuiltinFunction(Identifier Id, ArrayRef<Type> argTypes, Type ResType,
153153
Identifier(), SourceLoc(),
154154
Identifier(), argType,
155155
DC);
156+
PD->setInterfaceType(argType);
156157
PD->setImplicit();
157158
params.push_back(PD);
158159
}
@@ -204,10 +205,13 @@ getBuiltinGenericFunction(Identifier Id,
204205
DeclContext *DC = &M->getMainFile(FileUnitKind::Builtin);
205206

206207
SmallVector<ParamDecl*, 4> params;
207-
for (auto paramType : ArgBodyTypes) {
208+
for (unsigned i = 0, e = ArgParamTypes.size(); i < e; i++) {
209+
auto paramType = ArgBodyTypes[i];
210+
auto paramIfaceType = ArgParamTypes[i].getType();
208211
auto PD = new (Context) ParamDecl(/*IsLet*/true, SourceLoc(), SourceLoc(),
209212
Identifier(), SourceLoc(),
210213
Identifier(), paramType, DC);
214+
PD->setInterfaceType(paramIfaceType);
211215
PD->setImplicit();
212216
params.push_back(PD);
213217
}

0 commit comments

Comments
 (0)