Skip to content

Commit 1102835

Browse files
authored
Merge pull request #35589 from Jumhyn/placeholder-types
[AST, Sema] Replace HoleType with PlaceholderType
2 parents c9bb593 + 8539782 commit 1102835

Some content is hidden

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

45 files changed

+575
-275
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3543,6 +3543,9 @@ ERROR(generic_type_requires_arguments,none,
35433543
NOTE(descriptive_generic_type_declared_here,none,
35443544
"%0 declared here", (StringRef))
35453545

3546+
ERROR(placeholder_type_not_allowed,none,
3547+
"you cannot use a placeholder type here", ())
3548+
35463549
WARNING(use_of_void_pointer,none,
35473550
"Unsafe%0Pointer<Void> has been replaced by Unsafe%0RawPointer", (StringRef))
35483551

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797

9898
TYPE(Error, Type)
9999
UNCHECKED_TYPE(Unresolved, Type)
100-
UNCHECKED_TYPE(Hole, Type)
100+
UNCHECKED_TYPE(Placeholder, Type)
101101
ABSTRACT_TYPE(Builtin, Type)
102102
ABSTRACT_TYPE(AnyBuiltinInteger, BuiltinType)
103103
BUILTIN_TYPE(BuiltinInteger, AnyBuiltinIntegerType)

include/swift/AST/TypeRepr.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,34 @@ class OpaqueReturnTypeRepr : public TypeRepr {
10851085
friend class TypeRepr;
10861086
};
10871087

1088+
/// TypeRepr for a user-specified placeholder (essentially, a user-facing
1089+
/// representation of an anonymous type variable.
1090+
///
1091+
/// Can occur anywhere a normal type would occur, though usually expected to be
1092+
/// used in structural positions like \c Generic<Int,_>.
1093+
class PlaceholderTypeRepr: public TypeRepr {
1094+
SourceLoc UnderscoreLoc;
1095+
1096+
public:
1097+
PlaceholderTypeRepr(SourceLoc loc)
1098+
: TypeRepr(TypeReprKind::Placeholder), UnderscoreLoc(loc)
1099+
{}
1100+
1101+
SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; }
1102+
1103+
static bool classof(const TypeRepr *T) {
1104+
return T->getKind() == TypeReprKind::Placeholder;
1105+
}
1106+
static bool classof(const PlaceholderTypeRepr *T) { return true; }
1107+
1108+
private:
1109+
SourceLoc getStartLocImpl() const { return UnderscoreLoc; }
1110+
SourceLoc getEndLocImpl() const { return UnderscoreLoc; }
1111+
SourceLoc getLocImpl() const { return UnderscoreLoc; }
1112+
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
1113+
friend class TypeRepr;
1114+
};
1115+
10881116
/// SIL-only TypeRepr for box types.
10891117
///
10901118
/// Boxes are either concrete: { var Int, let String }
@@ -1198,6 +1226,7 @@ inline bool TypeRepr::isSimple() const {
11981226
case TypeReprKind::SILBox:
11991227
case TypeReprKind::Shared:
12001228
case TypeReprKind::Owned:
1229+
case TypeReprKind::Placeholder:
12011230
return true;
12021231
}
12031232
llvm_unreachable("bad TypeRepr kind");

include/swift/AST/TypeReprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ TYPEREPR(Composition, TypeRepr)
5454
TYPEREPR(Metatype, TypeRepr)
5555
TYPEREPR(Protocol, TypeRepr)
5656
TYPEREPR(OpaqueReturn, TypeRepr)
57+
TYPEREPR(Placeholder, TypeRepr)
5758
ABSTRACT_TYPEREPR(Specifier, TypeRepr)
5859
TYPEREPR(InOut, SpecifierTypeRepr)
5960
TYPEREPR(Shared, SpecifierTypeRepr)

include/swift/AST/Types.h

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class Identifier;
6767
class InOutType;
6868
class OpaqueTypeDecl;
6969
class OpenedArchetypeType;
70+
class PlaceholderTypeRepr;
7071
enum class ReferenceCounting : uint8_t;
7172
enum class ResilienceExpansion : unsigned;
7273
class SILModule;
@@ -126,7 +127,7 @@ class RecursiveTypeProperties {
126127

127128
/// This type expression contains an UnresolvedType.
128129
HasUnresolvedType = 0x08,
129-
130+
130131
/// Whether this type expression contains an unbound generic type.
131132
HasUnboundGeneric = 0x10,
132133

@@ -145,14 +146,14 @@ class RecursiveTypeProperties {
145146

146147
/// This type contains a DependentMemberType.
147148
HasDependentMember = 0x200,
148-
149+
149150
/// This type contains an OpaqueTypeArchetype.
150151
HasOpaqueArchetype = 0x400,
151152

152-
/// This type contains a type hole.
153-
HasTypeHole = 0x800,
153+
/// This type contains a type placeholder.
154+
HasPlaceholder = 0x800,
154155

155-
Last_Property = HasTypeHole
156+
Last_Property = HasPlaceholder
156157
};
157158
enum { BitWidth = countBitsUsed(Property::Last_Property) };
158159

@@ -207,9 +208,8 @@ class RecursiveTypeProperties {
207208
/// generic type?
208209
bool hasUnboundGeneric() const { return Bits & HasUnboundGeneric; }
209210

210-
/// Does a type with these properties structurally contain a
211-
/// type hole?
212-
bool hasTypeHole() const { return Bits & HasTypeHole; }
211+
/// Does a type with these properties structurally contain a placeholder?
212+
bool hasPlaceholder() const { return Bits & HasPlaceholder; }
213213

214214
/// Returns the set of properties present in either set.
215215
friend RecursiveTypeProperties operator|(Property lhs, Property rhs) {
@@ -546,7 +546,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
546546
/// Is this the 'Any' type?
547547
bool isAny();
548548

549-
bool isHole();
549+
bool isPlaceholder();
550550

551551
/// Does the type have outer parenthesis?
552552
bool hasParenSugar() const { return getKind() == TypeKind::Paren; }
@@ -580,8 +580,10 @@ class alignas(1 << TypeAlignInBits) TypeBase {
580580
return getRecursiveProperties().hasUnresolvedType();
581581
}
582582

583-
/// Determine whether this type involves a hole.
584-
bool hasHole() const { return getRecursiveProperties().hasTypeHole(); }
583+
/// Determine whether this type involves a \c PlaceholderType.
584+
bool hasPlaceholder() const {
585+
return getRecursiveProperties().hasPlaceholder();
586+
}
585587

586588
/// Determine whether the type involves a context-dependent archetype.
587589
bool hasArchetype() const {
@@ -5809,31 +5811,31 @@ TypeVariableType : public TypeBase {
58095811
};
58105812
DEFINE_EMPTY_CAN_TYPE_WRAPPER(TypeVariableType, Type)
58115813

5812-
/// HoleType - This represents a placeholder type for a type variable
5814+
/// PlaceholderType - This represents a placeholder type for a type variable
58135815
/// or dependent member type that cannot be resolved to a concrete type
58145816
/// because the expression is ambiguous. This type is only used by the
58155817
/// constraint solver and transformed into UnresolvedType to be used in AST.
5816-
class HoleType : public TypeBase {
5817-
using Originator = llvm::PointerUnion<TypeVariableType *,
5818-
DependentMemberType *, VarDecl *,
5819-
ErrorExpr *>;
5818+
class PlaceholderType : public TypeBase {
5819+
using Originator =
5820+
llvm::PointerUnion<TypeVariableType *, DependentMemberType *, VarDecl *,
5821+
ErrorExpr *, PlaceholderTypeRepr *>;
58205822

58215823
Originator O;
58225824

5823-
HoleType(ASTContext &C, Originator originator,
5824-
RecursiveTypeProperties properties)
5825-
: TypeBase(TypeKind::Hole, &C, properties), O(originator) {}
5825+
PlaceholderType(ASTContext &C, Originator originator,
5826+
RecursiveTypeProperties properties)
5827+
: TypeBase(TypeKind::Placeholder, &C, properties), O(originator) {}
58265828

58275829
public:
58285830
static Type get(ASTContext &ctx, Originator originator);
58295831

58305832
Originator getOriginator() const { return O; }
58315833

58325834
static bool classof(const TypeBase *T) {
5833-
return T->getKind() == TypeKind::Hole;
5835+
return T->getKind() == TypeKind::Placeholder;
58345836
}
58355837
};
5836-
DEFINE_EMPTY_CAN_TYPE_WRAPPER(HoleType, Type)
5838+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(PlaceholderType, Type)
58375839

58385840
inline bool TypeBase::isTypeVariableOrMember() {
58395841
if (is<TypeVariableType>())

include/swift/Sema/CSBindings.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct PotentialBinding {
138138

139139
static PotentialBinding forHole(TypeVariableType *typeVar,
140140
ConstraintLocator *locator) {
141-
return {HoleType::get(typeVar->getASTContext(), typeVar),
141+
return {PlaceholderType::get(typeVar->getASTContext(), typeVar),
142142
AllowedBindingKind::Exact,
143143
/*source=*/locator};
144144
}
@@ -307,9 +307,9 @@ struct PotentialBindings {
307307
bool isPotentiallyIncomplete() const;
308308

309309
/// If this type variable doesn't have any viable bindings, or
310-
/// if there is only one binding and it's a hole type, consider
310+
/// if there is only one binding and it's a placeholder type, consider
311311
/// this type variable to be a hole in a constraint system
312-
/// regardless of where hole type originated.
312+
/// regardless of where the placeholder type originated.
313313
bool isHole() const {
314314
if (isDirectHole())
315315
return true;
@@ -318,14 +318,14 @@ struct PotentialBindings {
318318
return false;
319319

320320
const auto &binding = Bindings.front();
321-
return binding.BindingType->is<HoleType>();
321+
return binding.BindingType->is<PlaceholderType>();
322322
}
323323

324324
/// Determines whether the only possible binding for this type variable
325-
/// would be a hole type. This is different from `isHole` method because
326-
/// type variable could also acquire a hole type transitively if one
327-
/// of the type variables in its subtype/equivalence chain has been
328-
/// bound to a hole type.
325+
/// would be a placeholder type. This is different from `isHole` method
326+
/// because type variable could also acquire a placeholder type transitively
327+
/// if one of the type variables in its subtype/equivalence chain has been
328+
/// bound to a placeholder type.
329329
bool isDirectHole() const;
330330

331331
/// Determine if the bindings only constrain the type variable from above

include/swift/Sema/ConstraintLocator.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,20 @@ class LocatorPathElt::ConformanceRequirement final
781781
}
782782
};
783783

784+
class LocatorPathElt::PlaceholderType final
785+
: public StoredPointerElement<PlaceholderTypeRepr> {
786+
public:
787+
PlaceholderType(PlaceholderTypeRepr *placeholderRepr)
788+
: StoredPointerElement(PathElementKind::PlaceholderType,
789+
placeholderRepr) {}
790+
791+
PlaceholderTypeRepr *getPlaceholderRepr() const { return getStoredPointer(); }
792+
793+
static bool classof(const LocatorPathElt *elt) {
794+
return elt->getKind() == ConstraintLocator::PlaceholderType;
795+
}
796+
};
797+
784798
namespace details {
785799
template <typename CustomPathElement>
786800
class PathElement {

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ SIMPLE_LOCATOR_PATH_ELT(UnresolvedMemberChainResult)
198198
/// The conformance requirement associated with a type.
199199
CUSTOM_LOCATOR_PATH_ELT(ConformanceRequirement)
200200

201+
/// A source-specified placeholder.
202+
CUSTOM_LOCATOR_PATH_ELT(PlaceholderType)
203+
201204
#undef LOCATOR_PATH_ELT
202205
#undef CUSTOM_LOCATOR_PATH_ELT
203206
#undef SIMPLE_LOCATOR_PATH_ELT

include/swift/Sema/ConstraintSystem.h

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ enum TypeVariableOptions {
255255
/// Whether the type variable can be bound to a non-escaping type or not.
256256
TVO_CanBindToNoEscape = 0x04,
257257

258-
/// Whether the type variable can be bound to a hole type or not.
258+
/// Whether the type variable can be bound to a hole or not.
259259
TVO_CanBindToHole = 0x08,
260260

261261
/// Whether a more specific deduction for this type variable implies a
@@ -327,7 +327,7 @@ class TypeVariableType::Implementation {
327327
/// Whether this type variable can bind to an inout type.
328328
bool canBindToNoEscape() const { return getRawOptions() & TVO_CanBindToNoEscape; }
329329

330-
/// Whether this type variable can bind to a hole type.
330+
/// Whether this type variable can bind to a hole.
331331
bool canBindToHole() const { return getRawOptions() & TVO_CanBindToHole; }
332332

333333
/// Whether this type variable prefers a subtype binding over a supertype
@@ -3759,14 +3759,15 @@ class ConstraintSystem {
37593759
Type openUnboundGenericType(GenericTypeDecl *decl, Type parentTy,
37603760
ConstraintLocatorBuilder locator);
37613761

3762-
/// "Open" the given type by replacing any occurrences of unbound
3763-
/// generic types with bound generic types with fresh type variables as
3764-
/// generic arguments.
3762+
/// Replace placeholder types with fresh type variables, and unbound generic
3763+
/// types with bound generic types whose generic args are fresh type
3764+
/// variables.
37653765
///
3766-
/// \param type The type to open.
3766+
/// \param type The type on which to perform the conversion.
37673767
///
3768-
/// \returns The opened type.
3769-
Type openUnboundGenericTypes(Type type, ConstraintLocatorBuilder locator);
3768+
/// \returns The converted type.
3769+
Type replaceInferableTypesWithTypeVars(Type type,
3770+
ConstraintLocatorBuilder locator);
37703771

37713772
/// "Open" the given type by replacing any occurrences of generic
37723773
/// parameter types and dependent member types with fresh type variables.
@@ -5024,6 +5025,26 @@ class OpenUnboundGenericType {
50245025
}
50255026
};
50265027

5028+
class HandlePlaceholderType {
5029+
ConstraintSystem &cs;
5030+
ConstraintLocator *locator;
5031+
5032+
public:
5033+
explicit HandlePlaceholderType(ConstraintSystem &cs,
5034+
const ConstraintLocatorBuilder &locator)
5035+
: cs(cs) {
5036+
this->locator = cs.getConstraintLocator(locator);
5037+
}
5038+
5039+
Type operator()(PlaceholderTypeRepr *placeholderRepr) const {
5040+
return cs.createTypeVariable(
5041+
cs.getConstraintLocator(
5042+
locator, LocatorPathElt::PlaceholderType(placeholderRepr)),
5043+
TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
5044+
TVO_CanBindToHole);
5045+
}
5046+
};
5047+
50275048
/// Compute the shuffle required to map from a given tuple type to
50285049
/// another tuple type.
50295050
///

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,9 +1517,8 @@ bool ASTContext::hadError() const {
15171517
/// Retrieve the arena from which we should allocate storage for a type.
15181518
static AllocationArena getArena(RecursiveTypeProperties properties) {
15191519
bool hasTypeVariable = properties.hasTypeVariable();
1520-
bool hasHole = properties.hasTypeHole();
1521-
return hasTypeVariable || hasHole ? AllocationArena::ConstraintSolver
1522-
: AllocationArena::Permanent;
1520+
return hasTypeVariable ? AllocationArena::ConstraintSolver
1521+
: AllocationArena::Permanent;
15231522
}
15241523

15251524
void ASTContext::addSearchPath(StringRef searchPath, bool isFramework,
@@ -2495,11 +2494,10 @@ Type ErrorType::get(Type originalType) {
24952494
return entry = new (mem) ErrorType(ctx, originalType, properties);
24962495
}
24972496

2498-
Type HoleType::get(ASTContext &ctx, Originator originator) {
2497+
Type PlaceholderType::get(ASTContext &ctx, Originator originator) {
24992498
assert(originator);
2500-
auto arena = getArena(RecursiveTypeProperties::HasTypeHole);
2501-
return new (ctx, arena)
2502-
HoleType(ctx, originator, RecursiveTypeProperties::HasTypeHole);
2499+
return new (ctx, AllocationArena::Permanent)
2500+
PlaceholderType(ctx, originator, RecursiveTypeProperties::HasPlaceholder);
25032501
}
25042502

25052503
BuiltinIntegerType *BuiltinIntegerType::get(BuiltinIntegerWidth BitWidth,
@@ -2943,7 +2941,7 @@ ReferenceStorageType *ReferenceStorageType::get(Type T,
29432941
ReferenceOwnership ownership,
29442942
const ASTContext &C) {
29452943
assert(!T->hasTypeVariable()); // not meaningful in type-checker
2946-
assert(!T->hasHole());
2944+
assert(!T->hasPlaceholder());
29472945
switch (optionalityOf(ownership)) {
29482946
case ReferenceOwnershipOptionality::Disallowed:
29492947
assert(!T->getOptionalObjectType() && "optional type is disallowed");
@@ -3330,7 +3328,7 @@ GenericFunctionType *GenericFunctionType::get(GenericSignature sig,
33303328
ExtInfo info) {
33313329
assert(sig && "no generic signature for generic function type?!");
33323330
assert(!result->hasTypeVariable());
3333-
assert(!result->hasHole());
3331+
assert(!result->hasPlaceholder());
33343332

33353333
llvm::FoldingSetNodeID id;
33363334
GenericFunctionType::Profile(id, sig, params, result, info);

0 commit comments

Comments
 (0)