Skip to content

Commit b044958

Browse files
authored
Merge pull request #60187 from gottesmm/moveonly_type_begin
[move-only] Implement very initial work for move only
2 parents e796ec7 + 65c21b6 commit b044958

24 files changed

+515
-21
lines changed

include/swift/AST/Attr.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,12 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(_local, KnownToBeLocal,
735735
APIBreakingToAdd | APIBreakingToRemove,
736736
130)
737737

738+
SIMPLE_DECL_ATTR(_moveOnly, MoveOnly,
739+
OnNominalType |
740+
UserInaccessible |
741+
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
742+
131)
743+
738744
// If you're adding a new underscored attribute here, please document it in
739745
// docs/ReferenceGuides/UnderscoredAttributes.md.
740746

include/swift/AST/Decl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,12 +2262,19 @@ class ValueDecl : public Decl {
22622262
/// Whether this declaration produces an implicitly unwrapped
22632263
/// optional result.
22642264
unsigned isIUO : 1;
2265+
2266+
/// Whether the "isMoveOnly" bit has been computed yet.
2267+
unsigned isMoveOnlyComputed : 1;
2268+
2269+
/// Whether this declaration can not be copied and thus is move only.
2270+
unsigned isMoveOnly : 1;
22652271
} LazySemanticInfo = { };
22662272

22672273
friend class DynamicallyReplacedDeclRequest;
22682274
friend class OverriddenDeclsRequest;
22692275
friend class IsObjCRequest;
22702276
friend class IsFinalRequest;
2277+
friend class IsMoveOnlyRequest;
22712278
friend class IsDynamicRequest;
22722279
friend class IsImplicitlyUnwrappedOptionalRequest;
22732280
friend class InterfaceTypeRequest;
@@ -2542,6 +2549,9 @@ class ValueDecl : public Decl {
25422549
/// Is this declaration 'final'?
25432550
bool isFinal() const;
25442551

2552+
/// Is this declaration 'moveOnly'?
2553+
bool isMoveOnly() const;
2554+
25452555
/// Is this declaration marked with 'dynamic'?
25462556
bool isDynamic() const;
25472557

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6396,5 +6396,8 @@ ERROR(concurrency_task_to_thread_model_global_actor_annotation,none,
63966396
"annotating a type with a global actor %0 is not permitted within %1",
63976397
(TypeRepr*, StringRef))
63986398

6399+
ERROR(moveOnly_not_allowed_here,none,
6400+
"'moveOnly' may only be applied to classes, structs, and enums", ())
6401+
63996402
#define UNDEFINE_DIAGNOSTIC_MACROS
64006403
#include "DefineDiagnosticMacros.h"

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,26 @@ class IsFinalRequest :
395395
void cacheResult(bool value) const;
396396
};
397397

398+
/// Determine whether the given declaration is 'moveOnly'.
399+
class IsMoveOnlyRequest
400+
: public SimpleRequest<IsMoveOnlyRequest, bool(ValueDecl *),
401+
RequestFlags::SeparatelyCached> {
402+
public:
403+
using SimpleRequest::SimpleRequest;
404+
405+
private:
406+
friend SimpleRequest;
407+
408+
// Evaluation.
409+
bool evaluate(Evaluator &evaluator, ValueDecl *decl) const;
410+
411+
public:
412+
// Separate caching.
413+
bool isCached() const { return true; }
414+
Optional<bool> getCachedResult() const;
415+
void cacheResult(bool value) const;
416+
};
417+
398418
/// Determine whether the given declaration is 'dynamic''.
399419
class IsDynamicRequest :
400420
public SimpleRequest<IsDynamicRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ SWIFT_REQUEST(TypeChecker, IsDynamicRequest, bool(ValueDecl *),
207207
SeparatelyCached, NoLocationInfo)
208208
SWIFT_REQUEST(TypeChecker, IsFinalRequest, bool(ValueDecl *), SeparatelyCached,
209209
NoLocationInfo)
210+
SWIFT_REQUEST(TypeChecker, IsMoveOnlyRequest, bool(ValueDecl *), SeparatelyCached,
211+
NoLocationInfo)
210212
SWIFT_REQUEST(TypeChecker, IsGetterMutatingRequest, bool(AbstractStorageDecl *),
211213
SeparatelyCached, NoLocationInfo)
212214
SWIFT_REQUEST(TypeChecker, IsImplicitlyUnwrappedOptionalRequest,

include/swift/SIL/SILInstruction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7587,8 +7587,8 @@ class MarkMustCheckInst
75877587
OwnershipForwardingMixin(SILInstructionKind::MarkMustCheckInst,
75887588
operand->getOwnershipKind()),
75897589
kind(checkKind) {
7590-
assert(operand->getType().isMoveOnlyWrapped() &&
7591-
"mark_must_check can only take a move only wrapped value");
7590+
assert(operand->getType().isMoveOnly() &&
7591+
"mark_must_check can only take a move only typed value");
75927592
}
75937593

75947594
public:

include/swift/SIL/SILType.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,10 @@ class SILType {
601601
/// Returns true if this is the AnyObject SILType;
602602
bool isAnyObject() const { return getASTType()->isAnyObject(); }
603603

604+
/// Returns true if this type is a first class move only type or a move only
605+
/// wrapped type.
606+
bool isMoveOnly() const;
607+
604608
/// Returns true if this SILType is a move only wrapper type.
605609
///
606610
/// Canonical way to check if a SILType is move only. Using is/getAs/castTo

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3102,6 +3102,12 @@ bool ValueDecl::isFinal() const {
31023102
getAttrs().hasAttribute<FinalAttr>());
31033103
}
31043104

3105+
bool ValueDecl::isMoveOnly() const {
3106+
return evaluateOrDefault(getASTContext().evaluator,
3107+
IsMoveOnlyRequest{const_cast<ValueDecl *>(this)},
3108+
getAttrs().hasAttribute<MoveOnlyAttr>());
3109+
}
3110+
31053111
bool ValueDecl::isDynamic() const {
31063112
ASTContext &ctx = getASTContext();
31073113
return evaluateOrDefault(ctx.evaluator,

lib/AST/TypeCheckRequests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,29 @@ void IsFinalRequest::cacheResult(bool value) const {
305305
decl->getAttrs().add(new (decl->getASTContext()) FinalAttr(/*Implicit=*/true));
306306
}
307307

308+
//----------------------------------------------------------------------------//
309+
// isMoveOnly computation.
310+
//----------------------------------------------------------------------------//
311+
312+
Optional<bool> IsMoveOnlyRequest::getCachedResult() const {
313+
auto decl = std::get<0>(getStorage());
314+
if (decl->LazySemanticInfo.isMoveOnlyComputed)
315+
return decl->LazySemanticInfo.isMoveOnly;
316+
317+
return None;
318+
}
319+
320+
void IsMoveOnlyRequest::cacheResult(bool value) const {
321+
auto decl = std::get<0>(getStorage());
322+
decl->LazySemanticInfo.isMoveOnlyComputed = true;
323+
decl->LazySemanticInfo.isMoveOnly = value;
324+
325+
// Add an attribute for printing
326+
if (value && !decl->getAttrs().hasAttribute<MoveOnlyAttr>())
327+
decl->getAttrs().add(new (decl->getASTContext())
328+
MoveOnlyAttr(/*Implicit=*/true));
329+
}
330+
308331
//----------------------------------------------------------------------------//
309332
// isDynamic computation.
310333
//----------------------------------------------------------------------------//

lib/SIL/IR/SILType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,3 +924,11 @@ SILType::getSingletonAggregateFieldType(SILModule &M,
924924

925925
return SILType();
926926
}
927+
928+
// TODO: Create isPureMoveOnly.
929+
bool SILType::isMoveOnly() const {
930+
if (auto *nom = getNominalOrBoundGenericNominal())
931+
if (nom->isMoveOnly())
932+
return true;
933+
return isMoveOnlyWrapped();
934+
}

0 commit comments

Comments
 (0)