Skip to content

Commit c66061a

Browse files
committed
[moveOnly] Add a new SIL specific AST type called SILMoveOnly.
It can only be used in SIL contexts to express that a wrapped type is MoveOnly.
1 parent 464d7ec commit c66061a

23 files changed

+140
-4
lines changed

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
333333
return asImpl().visit(type1->getCaptureType(), type2->getCaptureType());
334334
}
335335

336+
bool visitSILMoveOnlyType(CanSILMoveOnlyType type1,
337+
CanSILMoveOnlyType type2) {
338+
return asImpl().visit(type1->getInnerType(), type2->getInnerType());
339+
}
340+
336341
bool visitProtocolCompositionType(CanProtocolCompositionType type1,
337342
CanProtocolCompositionType type2) {
338343
return visitComponentArray(type1, type2,

include/swift/AST/TypeMatcher.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ class TypeMatcher {
352352
TRIVIAL_CASE(SILFunctionType)
353353
TRIVIAL_CASE(SILBlockStorageType)
354354
TRIVIAL_CASE(SILBoxType)
355+
TRIVIAL_CASE(SILMoveOnlyType)
355356

356357
bool visitProtocolCompositionType(CanProtocolCompositionType firstProtocolComposition,
357358
Type secondType,

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ ABSTRACT_TYPE(AnyFunction, Type)
159159
ARTIFICIAL_TYPE(SILFunction, Type)
160160
ARTIFICIAL_TYPE(SILBlockStorage, Type)
161161
ARTIFICIAL_TYPE(SILBox, Type)
162+
ARTIFICIAL_TYPE(SILMoveOnly, Type)
162163
ARTIFICIAL_TYPE(SILToken, Type)
163164
TYPE(ProtocolComposition, Type)
164165
TYPE(ParameterizedProtocol, Type)

include/swift/AST/Types.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4995,6 +4995,33 @@ class SILBoxType final : public TypeBase, public llvm::FoldingSetNode
49954995
};
49964996
DEFINE_EMPTY_CAN_TYPE_WRAPPER(SILBoxType, Type)
49974997

4998+
class SILMoveOnlyType;
4999+
class SILModule; // From SIL
5000+
typedef CanTypeWrapper<SILMoveOnlyType> CanMoveOnlyType;
5001+
5002+
/// A wrapper type that marks an inner type as being a move only value. Can not
5003+
/// be written directly at the Swift level, instead it is triggered by adding
5004+
/// the type attribute @_moveOnly to a different type. We transform these in
5005+
/// TypeLowering into a moveOnly SILType on the inner type.
5006+
class SILMoveOnlyType final : public TypeBase, public llvm::FoldingSetNode {
5007+
CanType innerType;
5008+
5009+
SILMoveOnlyType(CanType innerType)
5010+
: TypeBase(TypeKind::SILMoveOnly, &innerType->getASTContext(),
5011+
innerType->getRecursiveProperties()),
5012+
innerType(innerType) {}
5013+
5014+
public:
5015+
CanType getInnerType() const { return innerType; }
5016+
5017+
static CanMoveOnlyType get(CanType innerType);
5018+
5019+
static bool classof(const TypeBase *T) {
5020+
return T->getKind() == TypeKind::SILMoveOnly;
5021+
}
5022+
};
5023+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(SILMoveOnlyType, Type)
5024+
49985025
class SILBlockStorageType;
49995026
typedef CanTypeWrapper<SILBlockStorageType> CanSILBlockStorageType;
50005027

lib/AST/ASTContext.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ struct ASTContext::Implementation {
464464
llvm::FoldingSet<GenericFunctionType> GenericFunctionTypes;
465465
llvm::FoldingSet<SILFunctionType> SILFunctionTypes;
466466
llvm::DenseMap<CanType, SILBlockStorageType *> SILBlockStorageTypes;
467+
llvm::DenseMap<CanType, SILMoveOnlyType *> SILMoveOnlyTypes;
467468
llvm::FoldingSet<SILBoxType> SILBoxTypes;
468469
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
469470
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
@@ -4067,6 +4068,19 @@ SILFunctionType::SILFunctionType(
40674068
#endif
40684069
}
40694070

4071+
CanSILMoveOnlyType SILMoveOnlyType::get(CanType innerType) {
4072+
ASTContext &ctx = innerType->getASTContext();
4073+
auto found = ctx.getImpl().SILMoveOnlyTypes.find(innerType);
4074+
if (found != ctx.getImpl().SILMoveOnlyTypes.end())
4075+
return CanSILMoveOnlyType(found->second);
4076+
4077+
void *mem = ctx.Allocate(sizeof(SILMoveOnlyType), alignof(SILMoveOnlyType));
4078+
4079+
auto *storageTy = new (mem) SILMoveOnlyType(innerType);
4080+
ctx.getImpl().SILMoveOnlyTypes.insert({innerType, storageTy});
4081+
return CanSILMoveOnlyType(storageTy);
4082+
}
4083+
40704084
CanSILBlockStorageType SILBlockStorageType::get(CanType captureType) {
40714085
ASTContext &ctx = captureType->getASTContext();
40724086
auto found = ctx.getImpl().SILBlockStorageTypes.find(captureType);

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3935,6 +3935,12 @@ namespace {
39353935
PrintWithColorRAII(OS, ParenthesisColor) << ')';
39363936
}
39373937

3938+
void visitSILMoveOnlyType(SILMoveOnlyType *T, StringRef label) {
3939+
printCommon(label, "sil_move_only_type");
3940+
printRec(T->getInnerType());
3941+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3942+
}
3943+
39383944
void visitSILBoxType(SILBoxType *T, StringRef label) {
39393945
printCommon(label, "sil_box_type");
39403946
// FIXME: Print the structure of the type.

lib/AST/ASTMangler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1448,7 +1448,9 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
14481448

14491449
return;
14501450
}
1451-
1451+
case TypeKind::SILMoveOnly:
1452+
// If we hit this, we just mangle the underlying name and move on.
1453+
llvm_unreachable("should never be mangled?");
14521454
case TypeKind::SILBlockStorage:
14531455
llvm_unreachable("should never be mangled");
14541456
}

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6193,6 +6193,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
61936193
}
61946194
}
61956195

6196+
void visitSILMoveOnlyType(SILMoveOnlyType *T) {
6197+
Printer << "@moveOnly ";
6198+
printWithParensIfNotSimple(T->getInnerType());
6199+
}
6200+
61966201
void visitArraySliceType(ArraySliceType *T) {
61976202
Printer << "[";
61986203
visit(T->getBaseType());

lib/AST/ExistentialGeneralization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
175175
INVALID_TO_GENERALIZE(SILBox)
176176
INVALID_TO_GENERALIZE(SILFunction)
177177
INVALID_TO_GENERALIZE(SILToken)
178+
INVALID_TO_GENERALIZE(SILMoveOnly)
178179
#undef INVALID_TO_GENERALIZE
179180

180181
/// Generalize the generic arguments of the given generic type.s

lib/AST/Type.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
189189
case TypeKind::DynamicSelf:
190190
return isReferenceTypeImpl(cast<DynamicSelfType>(type).getSelfType(),
191191
sig, functionsCount);
192+
case TypeKind::SILMoveOnly:
193+
return isReferenceTypeImpl(cast<SILMoveOnlyType>(type)->getInnerType(), sig,
194+
functionsCount);
192195

193196
// Archetypes and existentials are only class references if class-bounded.
194197
case TypeKind::PrimaryArchetype:
@@ -1632,6 +1635,7 @@ CanType TypeBase::computeCanonicalType() {
16321635
case TypeKind::SILBox:
16331636
case TypeKind::SILFunction:
16341637
case TypeKind::SILToken:
1638+
case TypeKind::SILMoveOnly:
16351639
llvm_unreachable("SIL-only types are always canonical!");
16361640

16371641
case TypeKind::ProtocolComposition: {
@@ -5086,6 +5090,18 @@ case TypeKind::Id:
50865090
return storageTy;
50875091
}
50885092

5093+
case TypeKind::SILMoveOnly: {
5094+
auto *storageTy = cast<SILMoveOnlyType>(base);
5095+
Type transCap = storageTy->getInnerType().transformWithPosition(
5096+
TypePosition::Invariant, fn);
5097+
if (!transCap)
5098+
return Type();
5099+
CanType canTransCap = transCap->getCanonicalType();
5100+
if (canTransCap != storageTy->getInnerType())
5101+
return SILMoveOnlyType::get(canTransCap);
5102+
return storageTy;
5103+
}
5104+
50895105
case TypeKind::SILBox: {
50905106
bool changed = false;
50915107
auto boxTy = cast<SILBoxType>(base);
@@ -5996,6 +6012,8 @@ ReferenceCounting TypeBase::getReferenceCounting() {
59966012
case TypeKind::DynamicSelf:
59976013
return cast<DynamicSelfType>(type).getSelfType()
59986014
->getReferenceCounting();
6015+
case TypeKind::SILMoveOnly:
6016+
return cast<SILMoveOnlyType>(type)->getInnerType()->getReferenceCounting();
59996017

60006018
case TypeKind::PrimaryArchetype:
60016019
case TypeKind::OpenedArchetype:

0 commit comments

Comments
 (0)