Skip to content

Commit 8bc800f

Browse files
committed
[moveOnly] Add a Builtin.move operator that is overloaded over Builtin types.
Right now this does not actually do anything beyond causing a move_value instruction to be emitted. With time, I am going to use this to map T -> @_moveOnly T in the fullness of time... but I am going to stage in that part in a different commit once I add the MoveOnly type itself. I am trying to split up that larger commit as much as possible to make it easy to review.
1 parent 8cd8ca0 commit 8bc800f

File tree

6 files changed

+76
-0
lines changed

6 files changed

+76
-0
lines changed

include/swift/AST/ASTSynthesis.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,22 @@ Type synthesizeType(SynthesisContext &SC,
130130
return ExistentialMetatypeType::get(synthesizeType(SC, M.Sub));
131131
}
132132

133+
/// A synthesizer that generates a MoveOnly wrapper of a type.
134+
template <class S>
135+
struct MoveOnlyTypeSynthesizer {
136+
S Sub;
137+
};
138+
template <class S>
139+
constexpr MoveOnlyTypeSynthesizer<S> _moveOnly(S sub) {
140+
return {sub};
141+
}
142+
template <class S>
143+
Type synthesizeType(SynthesisContext &SC, const MoveOnlyTypeSynthesizer<S> &M) {
144+
// Until we get the actual move only type, we just return the synthesized
145+
// type.
146+
return synthesizeType(SC, M.Sub);
147+
}
148+
133149
/// Helper types for variadic synthesis.
134150
template <class... Ss>
135151
struct VariadicSynthesizerStorage;

include/swift/AST/Builtins.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,9 @@ BUILTIN_SIL_OPERATION(WithUnsafeThrowingContinuation, "withUnsafeThrowingContinu
515515
/// Force the current task to be rescheduled on the specified actor.
516516
BUILTIN_SIL_OPERATION(HopToActor, "hopToActor", None)
517517

518+
/// Generate a move_value instruction to convert a T to a @_moveOnly T.
519+
BUILTIN_SIL_OPERATION(Move, "move", Special)
520+
518521
#undef BUILTIN_SIL_OPERATION
519522

520523
// BUILTIN_RUNTIME_CALL - A call into a runtime function.

lib/AST/Builtins.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,12 @@ static ValueDecl *getDestroyArrayOperation(ASTContext &ctx, Identifier id) {
854854
_void);
855855
}
856856

857+
static ValueDecl *getMoveOperation(ASTContext &ctx, Identifier id) {
858+
return getBuiltinFunction(ctx, id, _thin, _generics(_unrestricted),
859+
_parameters(_owned(_typeparam(0))),
860+
_moveOnly(_typeparam(0)));
861+
}
862+
857863
static ValueDecl *getTransferArrayOperation(ASTContext &ctx, Identifier id) {
858864
return getBuiltinFunction(ctx, id, _thin,
859865
_generics(_unrestricted),
@@ -2500,6 +2506,11 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
25002506
if (!Types.empty()) return nullptr;
25012507
return getEndUnpairedAccessOperation(Context, Id);
25022508

2509+
case BuiltinValueKind::Move:
2510+
if (!Types.empty())
2511+
return nullptr;
2512+
return getMoveOperation(Context, Id);
2513+
25032514
#define BUILTIN(id, name, Attrs)
25042515
#define BUILTIN_BINARY_OPERATION(id, name, attrs)
25052516
#define BUILTIN_BINARY_OPERATION_OVERLOADED_STATIC(id, name, attrs, overload) \

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,15 @@ static ManagedValue emitBuiltinHopToActor(SILGenFunction &SGF, SILLocation loc,
15771577
return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
15781578
}
15791579

1580+
static ManagedValue emitBuiltinMove(SILGenFunction &SGF, SILLocation loc,
1581+
SubstitutionMap subs,
1582+
ArrayRef<ManagedValue> args, SGFContext C) {
1583+
assert(args.size() == 1 && "Move has a single argument");
1584+
auto firstArg = args[0].ensurePlusOne(SGF, loc);
1585+
CleanupCloner cloner(SGF, firstArg);
1586+
return cloner.clone(SGF.B.createMoveValue(loc, firstArg.forward(SGF)));
1587+
}
1588+
15801589
static ManagedValue emitBuiltinAutoDiffCreateLinearMapContext(
15811590
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
15821591
ArrayRef<ManagedValue> args, SGFContext C) {

test/SILGen/moveonly.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-emit-silgen -parse-stdlib %s -disable-access-control -disable-objc-attr-requires-foundation-module | %FileCheck %s
2+
3+
import Swift
4+
5+
class Klass {}
6+
7+
// CHECK-LABEL: sil hidden [ossa] @$s8moveonly7useMoveyAA5KlassCADF : $@convention(thin) (@guaranteed Klass) -> @owned Klass {
8+
// CHECK: bb0([[ARG:%.*]] :
9+
// CHECK-NEXT: debug_value
10+
// CHECK-NEXT: copy_value
11+
// CHECK-NEXT: move_value
12+
// CHECK-NEXT: return
13+
// CHECK: } // end sil function '$s8moveonly7useMoveyAA5KlassCADF'
14+
func useMove(_ k: Klass) -> Klass {
15+
Builtin.move(k)
16+
}
17+
18+
// CHECK-LABEL: sil hidden [ossa] @$s8moveonly7useMoveyxxRlzClF : $@convention(thin) <T where T : AnyObject> (@guaranteed T) -> @owned T {
19+
// CHECK: bb0([[ARG:%.*]] :
20+
// CHECK-NEXT: debug_value
21+
// CHECK-NEXT: copy_value
22+
// CHECK-NEXT: move_value
23+
// CHECK-NEXT: return
24+
// CHECK: } // end sil function '$s8moveonly7useMoveyxxRlzClF'
25+
func useMove<T : AnyObject>(_ k: T) -> T {
26+
Builtin.move(k)
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: not --crash %target-swift-emit-silgen -parse-stdlib %s -disable-access-control -disable-objc-attr-requires-foundation-module
2+
3+
// REQUIRES: asserts
4+
5+
// This test makes sure that we do not accept using Builtin.move on address only
6+
// types.
7+
8+
func addressOnlyMove<T>(t: T) -> T {
9+
Builtin.move(t)
10+
}

0 commit comments

Comments
 (0)