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:

lib/AST/TypeWalker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ class Traversal : public TypeVisitor<Traversal, bool>
234234
return doIt(ty->getCaptureType());
235235
}
236236

237+
bool visitSILMoveOnlyType(SILMoveOnlyType *ty) {
238+
return doIt(ty->getInnerType());
239+
}
240+
237241
bool visitSILBoxType(SILBoxType *ty) {
238242
for (Type type : ty->getSubstitutions().getReplacementTypes()) {
239243
if (type && doIt(type))

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,7 @@ class GetSendableType :
19191919
NEVER_VISIT(SILBlockStorageType)
19201920
NEVER_VISIT(SILBoxType)
19211921
NEVER_VISIT(SILTokenType)
1922+
NEVER_VISIT(SILMoveOnlyType)
19221923

19231924
VISIT(ProtocolCompositionType, compose)
19241925

lib/IRGen/GenType.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,8 @@ const TypeInfo *TypeConverter::convertType(CanType ty) {
21692169
case TypeKind::BoundGenericEnum:
21702170
case TypeKind::BoundGenericStruct:
21712171
return convertAnyNominalType(ty, cast<BoundGenericType>(ty)->getDecl());
2172+
case TypeKind::SILMoveOnly:
2173+
llvm_unreachable("implement this");
21722174
case TypeKind::InOut:
21732175
return convertInOutType(cast<InOutType>(ty));
21742176
case TypeKind::Tuple:

lib/IRGen/GenType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ class TypeConverter {
158158
const TypeInfo *convertBoxType(SILBoxType *T);
159159
const TypeInfo *convertArchetypeType(ArchetypeType *T);
160160
const TypeInfo *convertInOutType(InOutType *T);
161+
const TypeInfo *convertSILMoveOnlyType(SILMoveOnlyType *T) {
162+
return convertType(T->getInnerType());
163+
}
161164
const TypeInfo *convertExistentialMetatypeType(ExistentialMetatypeType *T);
162165
const TypeInfo *convertMetatypeType(MetatypeType *T);
163166
const TypeInfo *convertModuleType(ModuleType *T);

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17241724
case TypeKind::SILToken:
17251725
case TypeKind::BuiltinUnsafeValueBuffer:
17261726
case TypeKind::BuiltinDefaultActorStorage:
1727+
case TypeKind::SILMoveOnly:
17271728

17281729
LLVM_DEBUG(llvm::dbgs() << "Unhandled type: ";
17291730
DbgTy.getType()->dump(llvm::dbgs()); llvm::dbgs() << "\n");

lib/IRGen/MetadataRequest.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1941,7 +1941,10 @@ namespace {
19411941
DynamicMetadataRequest request) {
19421942
llvm_unreachable("should not be asking for metadata of a SILToken type");
19431943
}
1944-
1944+
MetadataResponse visitSILMoveOnlyType(CanSILMoveOnlyType type,
1945+
DynamicMetadataRequest request) {
1946+
llvm_unreachable("should not be asking for metadata of a move only type");
1947+
}
19451948
MetadataResponse visitArchetypeType(CanArchetypeType type,
19461949
DynamicMetadataRequest request) {
19471950
return emitArchetypeTypeMetadataRef(IGF, type, request);

lib/SIL/IR/TypeLowering.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,14 @@ namespace {
666666
type, getReferenceRecursiveProperties(isSensitive));
667667
}
668668

669+
RetTy visitSILMoveOnlyType(CanSILMoveOnlyType type,
670+
AbstractionPattern origType,
671+
IsTypeExpansionSensitive_t isSensitive) {
672+
return asImpl().handleReference(
673+
type->getInnerType()->getCanonicalType(),
674+
getReferenceRecursiveProperties(isSensitive));
675+
}
676+
669677
RetTy handleAggregateByProperties(CanType type, RecursiveProperties props) {
670678
if (props.isAddressOnly()) {
671679
return asImpl().handleAddressOnly(type, props);

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,7 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
28422842

28432843
// In SIL *only*, allow @moveOnly to specify a moveOnly type.
28442844
if ((options & TypeResolutionFlags::SILType) && attrs.has(TAK_moveOnly)) {
2845-
//ty = ty->getCanonicalType()->getMoveOnlyType();
2845+
ty = SILMoveOnlyType::get(ty->getCanonicalType());
28462846
attrs.clearAttribute(TAK_moveOnly);
28472847
}
28482848

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ TYPE(SIL_FUNCTION)
108108
TYPE(DYNAMIC_SELF)
109109
TYPE(EXISTENTIAL_METATYPE)
110110
TYPE(SIL_BLOCK_STORAGE)
111+
TYPE(SIL_MOVE_ONLY)
111112
TYPE(SIL_BOX)
112113
TYPE(NAME_ALIAS)
113114

lib/Serialization/Deserialization.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5939,6 +5939,13 @@ Expected<Type> DESERIALIZE_TYPE(SIL_BLOCK_STORAGE_TYPE)(
59395939
return SILBlockStorageType::get(MF.getType(captureID)->getCanonicalType());
59405940
}
59415941

5942+
Expected<Type> DESERIALIZE_TYPE(SIL_MOVE_ONLY_TYPE)(
5943+
ModuleFile &MF, SmallVectorImpl<uint64_t> &scratch, StringRef blobData) {
5944+
TypeID innerType;
5945+
decls_block::SILMoveOnlyTypeLayout::readRecord(scratch, innerType);
5946+
return SILMoveOnlyType::get(MF.getType(innerType)->getCanonicalType());
5947+
}
5948+
59425949
Expected<Type> DESERIALIZE_TYPE(SIL_BOX_TYPE)(
59435950
ModuleFile &MF, SmallVectorImpl<uint64_t> &scratch, StringRef blobData) {
59445951
SILLayoutID layoutID;

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 691; // bump to avoid conflict
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 692; // move only type wrapper
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -1208,6 +1208,11 @@ namespace decls_block {
12081208
TypeIDField // capture type
12091209
);
12101210

1211+
TYPE_LAYOUT(SILMoveOnlyTypeLayout,
1212+
SIL_MOVE_ONLY_TYPE,
1213+
TypeIDField // inner type
1214+
);
1215+
12111216
using SILLayoutLayout = BCRecordLayout<
12121217
SIL_LAYOUT,
12131218
GenericSignatureIDField, // generic signature

lib/Serialization/Serialization.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4720,6 +4720,11 @@ class Serializer::TypeSerializer : public TypeVisitor<TypeSerializer> {
47204720
storageTy->getCaptureType());
47214721
}
47224722

4723+
void visitSILMoveOnlyType(const SILMoveOnlyType *moveOnlyTy) {
4724+
using namespace decls_block;
4725+
serializeSimpleWrapper<SILMoveOnlyTypeLayout>(moveOnlyTy->getInnerType());
4726+
}
4727+
47234728
void visitSILBoxType(const SILBoxType *boxTy) {
47244729
using namespace decls_block;
47254730
unsigned abbrCode = S.DeclTypeAbbrCodes[SILBoxTypeLayout::Code];

test/SIL/Parser/basic2.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,19 @@ bb0(%0 : @owned $Builtin.NativeObject):
9797
%9999 = tuple()
9898
return %9999 : $()
9999
}
100+
101+
// Make sure that we properly can parse/print/round trip move only type annotation.
102+
// CHECK-LABEL: sil [ossa] @test_moveonlytype_parsing : $@convention(thin) (@owned @moveOnly Builtin.NativeObject) -> () {
103+
// CHECK: bb0(%0 : @owned $@moveOnly Builtin.NativeObject):
104+
// CHECK-NEXT: %1 = copy_value %0 : $@moveOnly Builtin.NativeObject
105+
// CHECK-NEXT: destroy_value %0 : $@moveOnly Builtin.NativeObject
106+
// CHECK-NEXT: destroy_value %1 : $@moveOnly Builtin.NativeObject
107+
// CHECK: } // end sil function 'test_moveonlytype_parsing'
108+
sil [ossa] @test_moveonlytype_parsing : $@convention(thin) (@owned @moveOnly Builtin.NativeObject) -> () {
109+
bb0(%0 : @owned $@moveOnly Builtin.NativeObject):
110+
%1 = copy_value %0 : $@moveOnly Builtin.NativeObject
111+
destroy_value %0 : $@moveOnly Builtin.NativeObject
112+
destroy_value %1 : $@moveOnly Builtin.NativeObject
113+
%9999 = tuple()
114+
return %9999 : $()
115+
}

0 commit comments

Comments
 (0)