Skip to content

Commit e000162

Browse files
committed
[move-only] Emit the move only marker for move only trivial enums.
Just an oversight I discovered when writing the enum deinit tests.
1 parent 99dcabd commit e000162

File tree

5 files changed

+54
-4
lines changed

5 files changed

+54
-4
lines changed

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ class SILType {
622622
/// wrapped type.
623623
bool isMoveOnly() const;
624624

625+
/// Is this a type that is a first class move only type. This returns false
626+
/// for a move only wrapped type.
627+
bool isPureMoveOnly() const;
628+
625629
/// Returns true if and only if this type is a first class move only
626630
/// type. NOTE: Returns false if the type is a move only wrapped type.
627631
bool isMoveOnlyType() const;

lib/SIL/IR/SILType.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,3 +948,10 @@ bool SILType::isMoveOnlyType() const {
948948
return true;
949949
return false;
950950
}
951+
952+
bool SILType::isPureMoveOnly() const {
953+
if (auto *nom = getNominalOrBoundGenericNominal())
954+
if (nom->isMoveOnly())
955+
return true;
956+
return false;
957+
}

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,6 +4248,7 @@ RValue CallEmission::applyEnumElementConstructor(SGFContext C) {
42484248
uncurriedLoc, std::move(payload),
42494249
SGF.getLoweredType(formalResultType),
42504250
element, uncurriedContext);
4251+
42514252
return RValue(SGF, uncurriedLoc, formalResultType, resultMV);
42524253
}
42534254

lib/SILGen/SILGenDecl.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,21 @@ class LetValueInitialization : public Initialization {
570570
SILValue value, bool wasPlusOne) {
571571
// If we have none...
572572
if (value->getOwnershipKind() == OwnershipKind::None) {
573-
// ... and we don't have a no implicit copy trivial type, just return
574-
// value.
575-
if (!SGF.getASTContext().LangOpts.Features.count(Feature::MoveOnly) ||
576-
!vd->isNoImplicitCopy() || !value->getType().isTrivial(SGF.F))
573+
// If we don't have move only features enabled, just return, we are done.
574+
if (!SGF.getASTContext().LangOpts.Features.count(Feature::MoveOnly))
575+
return value;
576+
577+
// Then check if we have a pure move only type. In that case, we need to
578+
// insert a no implicit copy
579+
if (value->getType().isPureMoveOnly()) {
580+
value = SGF.B.createMoveValue(PrologueLoc, value, /*isLexical*/ true);
581+
return SGF.B.createMarkMustCheckInst(
582+
PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
583+
}
584+
585+
// Otherwise, if we don't have a no implicit copy trivial type, just
586+
// return value.
587+
if (!vd->isNoImplicitCopy() || !value->getType().isTrivial(SGF.F))
577588
return value;
578589

579590
// Otherwise, we have a no implicit copy trivial type, so wrap it in the
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -enable-experimental-move-only -emit-silgen %s | %FileCheck %s
2+
3+
// This test makes sure that we properly setup enums when we construct moveonly
4+
// enums from literals.
5+
6+
@_moveOnly
7+
enum MoveOnlyIntPair {
8+
case lhs(Int)
9+
case rhs(Int)
10+
}
11+
12+
func consumeMoveIntPair(_ x: __owned MoveOnlyIntPair) {}
13+
14+
var value: Bool { false }
15+
16+
// CHECK-LABEL: sil hidden [ossa] @$s21moveonly_enum_literal4testyyF : $@convention(thin) () -> () {
17+
// CHECK: [[VALUE:%.*]] = enum $MoveOnlyIntPair, #MoveOnlyIntPair.lhs!enumelt,
18+
// CHECK: [[MV:%.*]] = move_value [lexical] [[VALUE]]
19+
// CHECK: [[MARKED_VALUE:%.*]] = mark_must_check [no_implicit_copy] [[MV]]
20+
// CHECK: debug_value [[MARKED_VALUE]]
21+
// CHECK: } // end sil function '$s21moveonly_enum_literal4testyyF'
22+
func test() {
23+
let x = MoveOnlyIntPair.lhs(5)
24+
if value {
25+
consumeMoveIntPair(x)
26+
}
27+
}

0 commit comments

Comments
 (0)