Skip to content

Commit c935d29

Browse files
authored
Merge pull request #66388 from gottesmm/release-5.9-rdar108383660
[5.9][borrowing][consuming] Make borrowing and consuming no implicit copy parameters
2 parents fdc89ab + 98cbeec commit c935d29

File tree

76 files changed

+3567
-527
lines changed

Some content is hidden

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

76 files changed

+3567
-527
lines changed

docs/SIL.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8460,6 +8460,33 @@ need for the guaranteed form in the future.
84608460
@moveOnly trivial type, we convert from the non-trivial representation to the
84618461
trivial representation.
84628462

8463+
copyable_to_moveonlywrapper_addr
8464+
````````````````````````````````
8465+
::
8466+
8467+
sil-instruction ::= 'copyable_to_moveonlywrapper_addr'
8468+
8469+
`copyable_to_moveonlywrapper_addr`_ takes in a '*T' and maps it to a move only
8470+
wrapped '*@moveOnly T'. This is semantically used by a code generator
8471+
initializing a new moveOnly binding from a copyable value. It semantically acts
8472+
as an address cast. If one thinks of '@moveOnly' as a monad, this is how one
8473+
injects a copyable value into the move only space.
8474+
8475+
moveonlywrapper_to_copyable_addr
8476+
````````````````````````````````
8477+
::
8478+
8479+
sil-instruction ::= 'moveonlywrapper_to_copyable_addr'
8480+
8481+
`moveonlywrapper_to_copyable_addr`_ takes in a '*@moveOnly T' and produces a new
8482+
'*T' value. This instruction acts like an address cast that projects out the
8483+
underlying T from an @moveOnly T.
8484+
8485+
NOTE: From the perspective of the address checker, a trivial `load`_ with a
8486+
`moveonlywrapper_to_copyable_addr`_ operand is considered to be a use of a
8487+
noncopyable type.
8488+
8489+
84638490
Assertion configuration
84648491
~~~~~~~~~~~~~~~~~~~~~~~
84658492

include/swift/AST/Decl.h

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,26 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, StaticSpellingKind SSK);
224224
/// Diagnostic printing of \c ReferenceOwnership.
225225
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceOwnership RO);
226226

227+
enum class SelfAccessKind : uint8_t {
228+
NonMutating,
229+
Mutating,
230+
LegacyConsuming,
231+
Consuming,
232+
Borrowing,
233+
LastSelfAccessKind = Borrowing,
234+
};
235+
enum : unsigned {
236+
NumSelfAccessKindBits =
237+
countBitsUsed(static_cast<unsigned>(SelfAccessKind::LastSelfAccessKind))
238+
};
239+
static_assert(uint8_t(SelfAccessKind::LastSelfAccessKind) <
240+
(NumSelfAccessKindBits << 1),
241+
"Self Access Kind is too small to fit in SelfAccess kind bits. "
242+
"Please expand ");
243+
244+
/// Diagnostic printing of \c SelfAccessKind.
245+
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);
246+
227247
/// Encapsulation of the overload signature of a given declaration,
228248
/// which is used to determine uniqueness of a declaration within a
229249
/// given context.
@@ -315,6 +335,10 @@ enum class ArtificialMainKind : uint8_t {
315335
/// Decl - Base class for all declarations in Swift.
316336
class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
317337
protected:
338+
// clang-format off
339+
//
340+
// We format these different than clang-format wishes us to... so turn if off
341+
// for the inline bitfields.
318342
union { uint64_t OpaqueBits;
319343

320344
SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+1,
@@ -456,7 +480,8 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
456480
DistributedThunk: 1
457481
);
458482

459-
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2+1,
483+
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl,
484+
1+1+2+1+1+NumSelfAccessKindBits+1,
460485
/// Whether we've computed the 'static' flag yet.
461486
IsStaticComputed : 1,
462487

@@ -473,7 +498,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
473498
SelfAccessComputed : 1,
474499

475500
/// Backing bits for 'self' access kind.
476-
SelfAccess : 2,
501+
SelfAccess : NumSelfAccessKindBits,
477502

478503
/// Whether this is a top-level function which should be treated
479504
/// as if it were in local context for the purposes of capture
@@ -735,6 +760,8 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
735760
);
736761

737762
} Bits;
763+
// Turn back on clang-format now that we have defined our inline bitfields.
764+
// clang-format on
738765

739766
// Storage for the declaration attributes.
740767
DeclAttributes Attrs;
@@ -7234,17 +7261,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
72347261

72357262
class OperatorDecl;
72367263

7237-
enum class SelfAccessKind : uint8_t {
7238-
NonMutating,
7239-
Mutating,
7240-
LegacyConsuming,
7241-
Consuming,
7242-
Borrowing,
7243-
};
7244-
7245-
/// Diagnostic printing of \c SelfAccessKind.
7246-
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);
7247-
72487264
/// FuncDecl - 'func' declaration.
72497265
class FuncDecl : public AbstractFunctionDecl {
72507266
friend class AbstractFunctionDecl;

include/swift/AST/DiagnosticsParse.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,11 @@ ERROR(sil_ref_inst_wrong_field,none,
602602
ERROR(sil_invalid_instr_operands,none,
603603
"invalid instruction operands", ())
604604
ERROR(sil_operand_not_address,none,
605-
"%0 operand of '%1' must have address type", (StringRef, StringRef))
605+
"%0 of '%1' must have address type", (StringRef, StringRef))
606+
ERROR(sil_operand_not_object,none,
607+
"%0 of '%1' must have object type", (StringRef, StringRef))
608+
ERROR(sil_operand_has_incorrect_moveonlywrapped,none,
609+
"%0 of '%1' %select{must|must not}2 be of moveonlywrapped type", (StringRef, StringRef, unsigned))
606610
ERROR(sil_operand_not_ref_storage_address,none,
607611
"%0 operand of '%1' must have address of %2 type",
608612
(StringRef, StringRef, ReferenceOwnership))
@@ -910,6 +914,8 @@ ERROR(sil_box_expected_r_brace,none,
910914
"expected '}' to complete SIL box field type list", ())
911915
ERROR(sil_box_expected_r_angle,none,
912916
"expected '>' to complete SIL box generic argument list", ())
917+
ERROR(sil_box_expected,none,
918+
"%0 expects its operand to be of SIL box field type", (StringRef))
913919

914920
// SIL function types
915921
ERROR(sil_function_subst_expected_l_angle,none,

include/swift/AST/Types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5291,7 +5291,9 @@ class SILMoveOnlyWrappedType final : public TypeBase,
52915291
SILMoveOnlyWrappedType(CanType innerType)
52925292
: TypeBase(TypeKind::SILMoveOnlyWrapped, &innerType->getASTContext(),
52935293
innerType->getRecursiveProperties()),
5294-
innerType(innerType) {}
5294+
innerType(innerType) {
5295+
assert(!innerType->isPureMoveOnly() && "Inner type must be copyable");
5296+
}
52955297

52965298
public:
52975299
CanType getInnerType() const { return innerType; }

include/swift/SIL/MemAccessUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,9 @@ inline bool isAccessStorageTypeCast(SingleValueInstruction *svi) {
15921592
default:
15931593
return false;
15941594
// Simply pass-thru the incoming address. But change its type!
1595+
case SILInstructionKind::MoveOnlyWrapperToCopyableAddrInst:
1596+
case SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst:
1597+
// Simply pass-thru the incoming address. But change its type!
15951598
case SILInstructionKind::UncheckedAddrCastInst:
15961599
// Casting to RawPointer does not affect the AccessPath. When converting
15971600
// between address types, they must be layout compatible (with truncation).

include/swift/SIL/SILBuilder.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,24 @@ class SILBuilder {
14101410
CopyableToMoveOnlyWrapperValueInst::Guaranteed));
14111411
}
14121412

1413+
MoveOnlyWrapperToCopyableBoxInst *
1414+
createMoveOnlyWrapperToCopyableBox(SILLocation loc, SILValue src) {
1415+
return insert(new (getModule()) MoveOnlyWrapperToCopyableBoxInst(
1416+
getSILDebugLocation(loc), src, src->getOwnershipKind()));
1417+
}
1418+
1419+
MoveOnlyWrapperToCopyableAddrInst *
1420+
createMoveOnlyWrapperToCopyableAddr(SILLocation loc, SILValue src) {
1421+
return insert(new (getModule()) MoveOnlyWrapperToCopyableAddrInst(
1422+
getSILDebugLocation(loc), src));
1423+
}
1424+
1425+
CopyableToMoveOnlyWrapperAddrInst *
1426+
createCopyableToMoveOnlyWrapperAddr(SILLocation loc, SILValue src) {
1427+
return insert(new (getModule()) CopyableToMoveOnlyWrapperAddrInst(
1428+
getSILDebugLocation(loc), src));
1429+
}
1430+
14131431
MoveOnlyWrapperToCopyableValueInst *
14141432
createOwnedMoveOnlyWrapperToCopyableValue(SILLocation loc, SILValue src) {
14151433
return insert(new (getModule()) MoveOnlyWrapperToCopyableValueInst(

include/swift/SIL/SILCloner.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,33 @@ void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableValueInst(
19421942
recordClonedInstruction(inst, cvt);
19431943
}
19441944

1945+
template <typename ImplClass>
1946+
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableBoxInst(
1947+
MoveOnlyWrapperToCopyableBoxInst *inst) {
1948+
getBuilder().setCurrentDebugScope(getOpScope(inst->getDebugScope()));
1949+
recordClonedInstruction(
1950+
inst, getBuilder().createMoveOnlyWrapperToCopyableBox(
1951+
getOpLocation(inst->getLoc()), getOpValue(inst->getOperand())));
1952+
}
1953+
1954+
template <typename ImplClass>
1955+
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableAddrInst(
1956+
MoveOnlyWrapperToCopyableAddrInst *inst) {
1957+
getBuilder().setCurrentDebugScope(getOpScope(inst->getDebugScope()));
1958+
recordClonedInstruction(
1959+
inst, getBuilder().createMoveOnlyWrapperToCopyableAddr(
1960+
getOpLocation(inst->getLoc()), getOpValue(inst->getOperand())));
1961+
}
1962+
1963+
template <typename ImplClass>
1964+
void SILCloner<ImplClass>::visitCopyableToMoveOnlyWrapperAddrInst(
1965+
CopyableToMoveOnlyWrapperAddrInst *inst) {
1966+
getBuilder().setCurrentDebugScope(getOpScope(inst->getDebugScope()));
1967+
recordClonedInstruction(
1968+
inst, getBuilder().createCopyableToMoveOnlyWrapperAddr(
1969+
getOpLocation(inst->getLoc()), getOpValue(inst->getOperand())));
1970+
}
1971+
19451972
template <typename ImplClass>
19461973
void SILCloner<ImplClass>::visitCopyableToMoveOnlyWrapperValueInst(
19471974
CopyableToMoveOnlyWrapperValueInst *inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,7 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) {
13971397
case SILInstructionKind::InitExistentialRefInst:
13981398
case SILInstructionKind::MarkDependenceInst:
13991399
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
1400+
case SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst:
14001401
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
14011402
return true;
14021403
default:
@@ -8482,10 +8483,21 @@ class CopyableToMoveOnlyWrapperValueInst
84828483
DebugLoc, operand, operand->getType().addingMoveOnlyWrapper(),
84838484
kind == InitialKind::Guaranteed ? OwnershipKind::Guaranteed
84848485
: OwnershipKind::Owned),
8485-
initialKind(kind) {}
8486+
initialKind(kind) {
8487+
assert(!operand->getType().isMoveOnly() &&
8488+
"Cannot be moveonly or moveonly wrapped");
8489+
}
84868490

84878491
public:
84888492
InitialKind getInitialKind() const { return initialKind; }
8493+
8494+
bool hasGuaranteedInitialKind() const {
8495+
return getInitialKind() == InitialKind::Guaranteed;
8496+
}
8497+
8498+
bool hasOwnedInitialKind() const {
8499+
return getInitialKind() == InitialKind::Owned;
8500+
}
84898501
};
84908502

84918503
/// Convert from an @moveOnly wrapper type to the underlying copyable type. Can
@@ -8534,10 +8546,71 @@ class MoveOnlyWrapperToCopyableValueInst
85348546
DebugLoc, operand, operand->getType().removingMoveOnlyWrapper(),
85358547
kind == InitialKind::Guaranteed ? OwnershipKind::Guaranteed
85368548
: OwnershipKind::Owned),
8537-
initialKind(kind) {}
8549+
initialKind(kind) {
8550+
assert(operand->getType().isMoveOnlyWrapped() &&
8551+
"Expected moveonlywrapped argument!");
8552+
}
85388553

85398554
public:
85408555
InitialKind getInitialKind() const { return initialKind; }
8556+
8557+
bool hasGuaranteedInitialKind() const {
8558+
return getInitialKind() == InitialKind::Guaranteed;
8559+
}
8560+
8561+
bool hasOwnedInitialKind() const {
8562+
return getInitialKind() == InitialKind::Owned;
8563+
}
8564+
};
8565+
8566+
/// Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that acts
8567+
/// similarly to an object cast like upcast, unlike
8568+
/// MoveOnlyWrapperToCopyableValue which provides artificial semantics injected
8569+
/// by SILGen.
8570+
class MoveOnlyWrapperToCopyableBoxInst
8571+
: public UnaryInstructionBase<
8572+
SILInstructionKind::MoveOnlyWrapperToCopyableBoxInst,
8573+
FirstArgOwnershipForwardingSingleValueInst> {
8574+
friend class SILBuilder;
8575+
8576+
MoveOnlyWrapperToCopyableBoxInst(SILDebugLocation DebugLoc, SILValue operand,
8577+
ValueOwnershipKind forwardingOwnershipKind)
8578+
: UnaryInstructionBase(
8579+
DebugLoc, operand,
8580+
operand->getType().removingMoveOnlyWrapperToBoxedType(
8581+
operand->getFunction()),
8582+
forwardingOwnershipKind) {
8583+
assert(
8584+
operand->getType().isBoxedMoveOnlyWrappedType(operand->getFunction()) &&
8585+
"Expected moveonlywrapped argument!");
8586+
}
8587+
};
8588+
8589+
class CopyableToMoveOnlyWrapperAddrInst
8590+
: public UnaryInstructionBase<
8591+
SILInstructionKind::CopyableToMoveOnlyWrapperAddrInst,
8592+
SingleValueInstruction> {
8593+
friend class SILBuilder;
8594+
8595+
CopyableToMoveOnlyWrapperAddrInst(SILDebugLocation DebugLoc, SILValue operand)
8596+
: UnaryInstructionBase(DebugLoc, operand,
8597+
operand->getType().addingMoveOnlyWrapper()) {
8598+
assert(!operand->getType().isMoveOnly() && "Expected copyable argument");
8599+
}
8600+
};
8601+
8602+
class MoveOnlyWrapperToCopyableAddrInst
8603+
: public UnaryInstructionBase<
8604+
SILInstructionKind::MoveOnlyWrapperToCopyableAddrInst,
8605+
SingleValueInstruction> {
8606+
friend class SILBuilder;
8607+
8608+
MoveOnlyWrapperToCopyableAddrInst(SILDebugLocation DebugLoc, SILValue operand)
8609+
: UnaryInstructionBase(DebugLoc, operand,
8610+
operand->getType().removingMoveOnlyWrapper()) {
8611+
assert(operand->getType().isMoveOnlyWrapped() &&
8612+
"Expected moveonlywrapped argument");
8613+
}
85418614
};
85428615

85438616
/// Given an object reference, return true iff it is non-nil and refers

include/swift/SIL/SILNodes.def

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,25 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
490490
// and owned for assignment/owned function arguments.
491491
SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperValueInst, copyable_to_moveonlywrapper,
492492
SingleValueInstruction, None, DoesNotRelease)
493-
// Convert a $@moveOnly T to $T. Ownership is fixed at construction by
493+
// Convert a $@moveOnly T object to $T. Ownership is fixed at construction by
494494
// frontend to express specific semantics: guaranteed for function arguments
495495
// and owned for assignment/return values.
496-
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableValueInst, moveonlywrapper_to_copyable,
497-
SingleValueInstruction, None, DoesNotRelease)
496+
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableValueInst,
497+
moveonlywrapper_to_copyable, SingleValueInstruction, None,
498+
DoesNotRelease)
499+
// Convert a ${ @moveOnly T } to $T. This is a forwarding instruction that
500+
// acts similarly to an object cast, unlike MoveOnlyWrapperToCopyableValue.
501+
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableBoxInst,
502+
moveonlywrapper_to_copyable_box, SingleValueInstruction, None,
503+
DoesNotRelease)
504+
// Convert a $*@moveOnly T to $*T. Acts just as a cast.
505+
SINGLE_VALUE_INST(MoveOnlyWrapperToCopyableAddrInst,
506+
moveonlywrapper_to_copyable_addr, SingleValueInstruction,
507+
None, DoesNotRelease)
508+
// Convert a $*T to $*@moveOnly T. Acts just as a cast.
509+
SINGLE_VALUE_INST(CopyableToMoveOnlyWrapperAddrInst,
510+
copyable_to_moveonlywrapper_addr, SingleValueInstruction,
511+
None, DoesNotRelease)
498512
// A move_addr is a Raw SIL only instruction that is equivalent to a copy_addr
499513
// [init]. It is lowered during the diagnostic passes to a copy_addr [init] if
500514
// the move checker found uses that prevented us from converting this to a

include/swift/SIL/SILType.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ class SILType {
721721
return getRawASTType()->is<SILMoveOnlyWrappedType>();
722722
}
723723

724-
/// If this is already a move only wrapped type, return *this. Otherwise, wrap
725-
/// the copyable type in the mov eonly wrapper.
724+
/// If this is already a moveonlywrapped type, return *this. Otherwise, wrap
725+
/// the copyable type in the moveonlywrapper.
726726
SILType addingMoveOnlyWrapper() const {
727727
if (isMoveOnlyWrapped())
728728
return *this;
@@ -749,6 +749,20 @@ class SILType {
749749
return *this;
750750
}
751751

752+
/// If this is a box type containing a moveonlywrapped type, return a new box
753+
/// with the moveonlywrapped type unwrapped.
754+
///
755+
/// DISCUSSION: This is separate from addingMoveOnlyWrapper since this API
756+
/// requires a SILFunction * and is specialized.
757+
SILType addingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
758+
759+
/// If this is a box type containing a copyable type, return a new box type
760+
/// with the copyable type wrapped in a moveonly wrapped type.
761+
///
762+
/// DISCUSSION: This is separate from removingMoveOnlyWrapper since this API
763+
/// requires a SILFunction * and is specialized.
764+
SILType removingMoveOnlyWrapperToBoxedType(const SILFunction *fn);
765+
752766
/// Returns a SILType with any archetypes mapped out of context.
753767
SILType mapTypeOutOfContext() const;
754768

@@ -799,6 +813,12 @@ class SILType {
799813
return isBoxedNonCopyableType(&fn);
800814
}
801815

816+
bool isBoxedMoveOnlyWrappedType(const SILFunction *fn) const {
817+
if (!this->is<SILBoxType>())
818+
return false;
819+
return getSILBoxFieldType(fn).isMoveOnlyWrapped();
820+
}
821+
802822
SILType getInstanceTypeOfMetatype(SILFunction *function) const;
803823

804824
bool isOrContainsObjectiveCClass() const;

0 commit comments

Comments
 (0)