Skip to content

Commit 681a2b7

Browse files
authored
Merge pull request swiftlang#69164 from atrick/nonescapable_attr
Add a temporary @_nonEscapable and @_hasUnsafeNonEscapableResult attribute
2 parents 23701bb + 1f521cd commit 681a2b7

27 files changed

+198
-7
lines changed

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
116116
}
117117
}
118118

119+
public var hasUnsafeNonEscapableResult: Bool {
120+
return bridged.hasUnsafeNonEscapableResult()
121+
}
122+
119123
/// True if the callee function is annotated with @_semantics("programtermination_point").
120124
/// This means that the function terminates the program.
121125
public var isProgramTerminationPoint: Bool { hasSemanticsAttribute("programtermination_point") }

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
5858
public var isMetatype: Bool { bridged.isMetatype() }
5959
public var isNoEscapeFunction: Bool { bridged.isNoEscapeFunction() }
6060
public var isAsyncFunction: Bool { bridged.isAsyncFunction() }
61+
public var isEscapable: Bool { bridged.isEscapable() }
6162

6263
public var canBeClass: BridgedType.TraitResult { bridged.canBeClass() }
6364

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,15 @@ This is the default behavior, unless the type annotated is an aggregate that
625625
consists entirely of `@_eagerMove` or trivial values, in which case the
626626
attribute overrides the inferred type-level annotation.
627627

628+
## `@_nonEscapable`
629+
630+
Indicates that a type is non-escapable. All instances of this type are
631+
non-escaping values. A non-escaping value's lifetime must be confined
632+
to another "parent" lifetime.
633+
634+
This is temporary until ~Escapable syntax is supported, which will
635+
also work as a generic type constraint.
636+
628637
## `@_marker`
629638

630639
Indicates that a protocol is a marker protocol. Marker protocols represent some

include/swift/AST/Attr.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ DECL_ATTR(_rawLayout, RawLayout,
423423
DECL_ATTR(_extern, Extern,
424424
OnFunc | ABIStableToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,
425425
147)
426+
SIMPLE_DECL_ATTR(_nonEscapable, NonEscapable,
427+
OnNominalType | UserInaccessible | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
428+
148)
429+
SIMPLE_DECL_ATTR(_unsafeNonEscapableResult, UnsafeNonEscapableResult,
430+
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIBreakingToRemove,
431+
149)
426432
CONTEXTUAL_SIMPLE_DECL_ATTR(final, Final,
427433
OnClass | OnFunc | OnAccessor | OnVar | OnSubscript | DeclModifier | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,
428434
2)

include/swift/AST/Decl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,13 +2611,20 @@ class ValueDecl : public Decl {
26112611

26122612
/// Whether this declaration can not be copied and thus is move only.
26132613
unsigned isMoveOnly : 1;
2614+
2615+
/// Whether the "isEscapable" bit has been computed yet.
2616+
unsigned isEscapable : 1;
2617+
2618+
/// Whether this declaration is escapable.
2619+
unsigned isEscapableComputed : 1;
26142620
} LazySemanticInfo = { };
26152621

26162622
friend class DynamicallyReplacedDeclRequest;
26172623
friend class OverriddenDeclsRequest;
26182624
friend class IsObjCRequest;
26192625
friend class IsFinalRequest;
26202626
friend class IsMoveOnlyRequest;
2627+
friend class IsEscapableRequest;
26212628
friend class IsDynamicRequest;
26222629
friend class IsImplicitlyUnwrappedOptionalRequest;
26232630
friend class InterfaceTypeRequest;
@@ -2923,6 +2930,9 @@ class ValueDecl : public Decl {
29232930
/// Is this declaration 'moveOnly'?
29242931
bool isMoveOnly() const;
29252932

2933+
/// Is this declaration escapable?
2934+
bool isEscapable() const;
2935+
29262936
/// Is this declaration marked with 'dynamic'?
29272937
bool isDynamic() const;
29282938

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7539,6 +7539,9 @@ ERROR(noncopyable_cannot_have_read_set_accessor,none,
75397539
"noncopyable %select{variable|subscript}0 cannot provide a read and set accessor",
75407540
(unsigned))
75417541

7542+
ERROR(nonescapable_types_attr_disabled,none,
7543+
"attribute requires '-enable-experimental-feature NonEscapableTypes'", ())
7544+
75427545
//------------------------------------------------------------------------------
75437546
// MARK: Init accessors
75447547
//------------------------------------------------------------------------------

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,27 @@ class IsMoveOnlyRequest
427427
void cacheResult(bool value) const;
428428
};
429429

430+
431+
/// Determine whether the given declaration is escapable.
432+
class IsEscapableRequest
433+
: public SimpleRequest<IsEscapableRequest, bool(ValueDecl *),
434+
RequestFlags::SeparatelyCached> {
435+
public:
436+
using SimpleRequest::SimpleRequest;
437+
438+
private:
439+
friend SimpleRequest;
440+
441+
// Evaluation.
442+
bool evaluate(Evaluator &evaluator, ValueDecl *decl) const;
443+
444+
public:
445+
// Separate caching.
446+
bool isCached() const { return true; }
447+
llvm::Optional<bool> getCachedResult() const;
448+
void cacheResult(bool value) const;
449+
};
450+
430451
/// Determine whether the given declaration is 'dynamic''.
431452
class IsDynamicRequest :
432453
public SimpleRequest<IsDynamicRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ SWIFT_REQUEST(TypeChecker, IsFinalRequest, bool(ValueDecl *), SeparatelyCached,
212212
NoLocationInfo)
213213
SWIFT_REQUEST(TypeChecker, IsMoveOnlyRequest, bool(ValueDecl *), SeparatelyCached,
214214
NoLocationInfo)
215+
SWIFT_REQUEST(TypeChecker, IsEscapableRequest, bool(ValueDecl *),
216+
SeparatelyCached, NoLocationInfo)
215217
SWIFT_REQUEST(TypeChecker, IsGetterMutatingRequest, bool(AbstractStorageDecl *),
216218
SeparatelyCached, NoLocationInfo)
217219
SWIFT_REQUEST(TypeChecker, IsImplicitlyUnwrappedOptionalRequest,

include/swift/Basic/Features.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ EXPERIMENTAL_FEATURE(TypedThrows, true)
252252
/// Allow destructuring stored `let` bindings in structs.
253253
EXPERIMENTAL_FEATURE(StructLetDestructuring, true)
254254

255+
/// Enable non-escapable type attributes and function attributes that support
256+
/// lifetime-dependent results.
257+
EXPERIMENTAL_FEATURE(NonEscapableTypes, false)
258+
255259
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
256260
#undef EXPERIMENTAL_FEATURE
257261
#undef UPCOMING_FEATURE

include/swift/SIL/SILBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct BridgedType {
110110
BRIDGED_INLINE bool isAsyncFunction() const;
111111
BRIDGED_INLINE TraitResult canBeClass() const;
112112
BRIDGED_INLINE bool isMoveOnly() const;
113+
BRIDGED_INLINE bool isEscapable() const;
113114
BRIDGED_INLINE bool isOrContainsObjectiveCClass() const;
114115
BRIDGED_INLINE bool isBuiltinInteger() const;
115116
BRIDGED_INLINE bool isBuiltinFloat() const;
@@ -328,6 +329,7 @@ struct BridgedFunction {
328329
BRIDGED_INLINE bool isDestructor() const;
329330
BRIDGED_INLINE bool isGenericFunction() const;
330331
BRIDGED_INLINE bool hasSemanticsAttr(BridgedStringRef attrName) const;
332+
BRIDGED_INLINE bool hasUnsafeNonEscapableResult() const;
331333
BRIDGED_INLINE EffectsKind getEffectAttribute() const;
332334
BRIDGED_INLINE PerformanceConstraints getPerformanceConstraints() const;
333335
BRIDGED_INLINE InlineStrategy getInlineStrategy() const;

0 commit comments

Comments
 (0)