Skip to content

Commit 78ea3de

Browse files
committed
[AST] Introduce a new type to represent a type hole in constraint system
Instead of using `UnresolvedType` as a placeholder for a type hole, let's switch over to a dedicated "rich" `HoleType` which is capable of storing "originator" type - type variable or dependent member type which couldn't be resolved. This makes it easier for the solver to determine origins of a hole which helps to diagnose certain problems better. It also helps code completion to locate "expected type" of the context even when it couldn't be completely resolved.
1 parent a350fb7 commit 78ea3de

File tree

11 files changed

+81
-9
lines changed

11 files changed

+81
-9
lines changed

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989

9090
TYPE(Error, Type)
9191
UNCHECKED_TYPE(Unresolved, Type)
92+
UNCHECKED_TYPE(Hole, Type)
9293
ABSTRACT_TYPE(Builtin, Type)
9394
ABSTRACT_TYPE(AnyBuiltinInteger, BuiltinType)
9495
BUILTIN_TYPE(BuiltinInteger, AnyBuiltinIntegerType)

include/swift/AST/Types.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ class RecursiveTypeProperties {
148148
/// This type contains an OpaqueTypeArchetype.
149149
HasOpaqueArchetype = 0x400,
150150

151-
Last_Property = HasOpaqueArchetype
151+
/// This type constains a type hole.
152+
HasTypeHole = 0x800,
153+
154+
Last_Property = HasTypeHole
152155
};
153156
enum { BitWidth = countBitsUsed(Property::Last_Property) };
154157

@@ -203,6 +206,10 @@ class RecursiveTypeProperties {
203206
/// generic type?
204207
bool hasUnboundGeneric() const { return Bits & HasUnboundGeneric; }
205208

209+
/// Does a type with these properties structurally contain a
210+
/// type hole?
211+
bool hasTypeHole() const { return Bits & HasTypeHole; }
212+
206213
/// Returns the set of properties present in either set.
207214
friend RecursiveTypeProperties operator|(Property lhs, Property rhs) {
208215
return RecursiveTypeProperties(unsigned(lhs) | unsigned(rhs));
@@ -574,9 +581,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
574581
}
575582

576583
/// Determine whether this type involves a hole.
577-
bool hasHole() const {
578-
return getRecursiveProperties().hasUnresolvedType();
579-
}
584+
bool hasHole() const { return getRecursiveProperties().hasTypeHole(); }
580585

581586
/// Determine whether the type involves a context-dependent archetype.
582587
bool hasArchetype() const {
@@ -5728,6 +5733,31 @@ TypeVariableType : public TypeBase {
57285733
};
57295734
DEFINE_EMPTY_CAN_TYPE_WRAPPER(TypeVariableType, Type)
57305735

5736+
/// HoleType - This represents a placeholder type for a type variable
5737+
/// or dependent member type that cannot be resolved to a concrete type
5738+
/// because the expression is ambiguous. This type is only used by the
5739+
/// constraint solver and transformed into UnresolvedType to be used in AST.
5740+
class HoleType : public TypeBase {
5741+
using OriginatorType =
5742+
llvm::PointerUnion<TypeVariableType *, DependentMemberType *>;
5743+
5744+
OriginatorType Originator;
5745+
5746+
HoleType(ASTContext &C, OriginatorType originator,
5747+
RecursiveTypeProperties properties)
5748+
: TypeBase(TypeKind::Hole, &C, properties), Originator(originator) {}
5749+
5750+
public:
5751+
static Type get(ASTContext &ctx, OriginatorType originatorType);
5752+
5753+
OriginatorType getOriginatorType() const { return Originator; }
5754+
5755+
static bool classof(const TypeBase *T) {
5756+
return T->getKind() == TypeKind::Hole;
5757+
}
5758+
};
5759+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(HoleType, Type)
5760+
57315761
inline bool TypeBase::isTypeVariableOrMember() {
57325762
if (is<TypeVariableType>())
57335763
return true;

lib/AST/ASTContext.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,13 @@ Type ErrorType::get(Type originalType) {
23582358
return entry = new (mem) ErrorType(ctx, originalType, properties);
23592359
}
23602360

2361+
Type HoleType::get(ASTContext &ctx, OriginatorType originator) {
2362+
assert(originator);
2363+
RecursiveTypeProperties properties = RecursiveTypeProperties::HasTypeHole;
2364+
auto arena = getArena(properties);
2365+
return new (ctx, arena) HoleType(ctx, originator, properties);
2366+
}
2367+
23612368
BuiltinIntegerType *BuiltinIntegerType::get(BuiltinIntegerWidth BitWidth,
23622369
const ASTContext &C) {
23632370
assert(!BitWidth.isArbitraryWidth());
@@ -2957,7 +2964,7 @@ isFunctionTypeCanonical(ArrayRef<AnyFunctionType::Param> params,
29572964
static RecursiveTypeProperties
29582965
getGenericFunctionRecursiveProperties(ArrayRef<AnyFunctionType::Param> params,
29592966
Type result) {
2960-
static_assert(RecursiveTypeProperties::BitWidth == 11,
2967+
static_assert(RecursiveTypeProperties::BitWidth == 12,
29612968
"revisit this if you add new recursive type properties");
29622969
RecursiveTypeProperties properties;
29632970

@@ -3513,7 +3520,7 @@ CanSILFunctionType SILFunctionType::get(
35133520
void *mem = ctx.Allocate(bytes, alignof(SILFunctionType));
35143521

35153522
RecursiveTypeProperties properties;
3516-
static_assert(RecursiveTypeProperties::BitWidth == 11,
3523+
static_assert(RecursiveTypeProperties::BitWidth == 12,
35173524
"revisit this if you add new recursive type properties");
35183525
for (auto &param : params)
35193526
properties |= param.getInterfaceType()->getRecursiveProperties();

lib/AST/ASTDumper.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3496,6 +3496,18 @@ namespace {
34963496

34973497
TRIVIAL_TYPE_PRINTER(Unresolved, unresolved)
34983498

3499+
void visitHoleType(HoleType *T, StringRef label) {
3500+
printCommon(label, "hole_type");
3501+
auto originatorTy = T->getOriginatorType();
3502+
if (auto *typeVar = originatorTy.dyn_cast<TypeVariableType *>()) {
3503+
printRec("type_variable", typeVar);
3504+
} else {
3505+
printRec("dependent_member_type",
3506+
originatorTy.get<DependentMemberType *>());
3507+
}
3508+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3509+
}
3510+
34993511
void visitBuiltinIntegerType(BuiltinIntegerType *T, StringRef label) {
35003512
printCommon(label, "builtin_integer_type");
35013513
if (T->isFixedWidth())

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ void ASTMangler::appendType(Type type, const ValueDecl *forDecl) {
915915
TypeBase *tybase = type.getPointer();
916916
switch (type->getKind()) {
917917
case TypeKind::TypeVariable:
918+
case TypeKind::Hole:
918919
llvm_unreachable("mangling type variable");
919920

920921
case TypeKind::Module:

lib/AST/ASTPrinter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3813,6 +3813,17 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
38133813
Printer << "_";
38143814
}
38153815

3816+
void visitHoleType(HoleType *T) {
3817+
if (Options.PrintTypesForDebugging) {
3818+
Printer << "<<hole for ";
3819+
auto originatorTy = T->getOriginatorType();
3820+
visit(Type(reinterpret_cast<TypeBase *>(originatorTy.getOpaqueValue())));
3821+
Printer << ">>";
3822+
} else {
3823+
Printer << "<<hole>>";
3824+
}
3825+
}
3826+
38163827
#ifdef ASTPRINTER_HANDLE_BUILTINTYPE
38173828
#error "ASTPRINTER_HANDLE_BUILTINTYPE should not be defined?!"
38183829
#endif

lib/AST/Type.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,7 @@ bool TypeBase::isAny() {
153153
return isEqual(getASTContext().TheAnyType);
154154
}
155155

156-
bool TypeBase::isHole() {
157-
return isEqual(getASTContext().TheUnresolvedType);
158-
}
156+
bool TypeBase::isHole() { return getCanonicalType()->is<HoleType>(); }
159157

160158
bool TypeBase::isAnyClassReferenceType() {
161159
return getCanonicalType().isAnyClassReferenceType();
@@ -221,6 +219,7 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
221219
case TypeKind::LValue:
222220
case TypeKind::InOut:
223221
case TypeKind::TypeVariable:
222+
case TypeKind::Hole:
224223
case TypeKind::BoundGenericEnum:
225224
case TypeKind::BoundGenericStruct:
226225
case TypeKind::SILToken:
@@ -1149,6 +1148,7 @@ CanType TypeBase::computeCanonicalType() {
11491148
case TypeKind::Error:
11501149
case TypeKind::Unresolved:
11511150
case TypeKind::TypeVariable:
1151+
case TypeKind::Hole:
11521152
llvm_unreachable("these types are always canonical");
11531153

11541154
#define SUGARED_TYPE(id, parent) \
@@ -4244,6 +4244,7 @@ case TypeKind::Id:
42444244
case TypeKind::Error:
42454245
case TypeKind::Unresolved:
42464246
case TypeKind::TypeVariable:
4247+
case TypeKind::Hole:
42474248
case TypeKind::GenericTypeParam:
42484249
case TypeKind::SILToken:
42494250
case TypeKind::Module:
@@ -4983,6 +4984,7 @@ ReferenceCounting TypeBase::getReferenceCounting() {
49834984
case TypeKind::LValue:
49844985
case TypeKind::InOut:
49854986
case TypeKind::TypeVariable:
4987+
case TypeKind::Hole:
49864988
case TypeKind::BoundGenericEnum:
49874989
case TypeKind::BoundGenericStruct:
49884990
case TypeKind::SILToken:

lib/AST/TypeWalker.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Traversal : public TypeVisitor<Traversal, bool>
3434

3535
bool visitErrorType(ErrorType *ty) { return false; }
3636
bool visitUnresolvedType(UnresolvedType *ty) { return false; }
37+
bool visitHoleType(HoleType *ty) { return false; }
3738
bool visitBuiltinType(BuiltinType *ty) { return false; }
3839
bool visitTypeAliasType(TypeAliasType *ty) {
3940
if (auto parent = ty->getParent())

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
15711571
case TypeKind::Unresolved:
15721572
case TypeKind::LValue:
15731573
case TypeKind::TypeVariable:
1574+
case TypeKind::Hole:
15741575
case TypeKind::Module:
15751576
case TypeKind::SILBlockStorage:
15761577
case TypeKind::SILBox:

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4685,6 +4685,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
46854685

46864686
case TypeKind::Error:
46874687
case TypeKind::Unresolved:
4688+
case TypeKind::Hole:
46884689
return getTypeMatchFailure(locator);
46894690

46904691
case TypeKind::GenericTypeParam:
@@ -5366,6 +5367,7 @@ ConstraintSystem::simplifyConstructionConstraint(
53665367

53675368
case TypeKind::Unresolved:
53685369
case TypeKind::Error:
5370+
case TypeKind::Hole:
53695371
return SolutionKind::Error;
53705372

53715373
case TypeKind::GenericFunction:

0 commit comments

Comments
 (0)