@@ -95,6 +95,65 @@ struct DenseMapInfo<swift::PartitionPrimitives::Region> {
9595
9696namespace swift {
9797
98+ class ActorInstance {
99+ public:
100+ enum class Kind : uint8_t {
101+ Value,
102+ ActorAccessorInit = 0x1 ,
103+ };
104+
105+ llvm::PointerIntPair<SILValue, 1 > value;
106+
107+ ActorInstance (SILValue value, Kind kind)
108+ : value(value, std::underlying_type<Kind>::type(kind)) {}
109+
110+ public:
111+ ActorInstance () : ActorInstance(SILValue(), Kind::Value) {}
112+
113+ static ActorInstance getForValue (SILValue value) {
114+ return ActorInstance (value, Kind::Value);
115+ }
116+
117+ static ActorInstance getForActorAccessorInit () {
118+ return ActorInstance (SILValue (), Kind::ActorAccessorInit);
119+ }
120+
121+ explicit operator bool () const { return bool (value.getOpaqueValue ()); }
122+
123+ Kind getKind () const { return Kind (value.getInt ()); }
124+
125+ SILValue getValue () const {
126+ assert (getKind () == Kind::Value);
127+ return value.getPointer ();
128+ }
129+
130+ bool isValue () const { return getKind () == Kind::Value; }
131+
132+ bool isAccessorInit () const { return getKind () == Kind::ActorAccessorInit; }
133+
134+ bool operator ==(const ActorInstance &other) const {
135+ // If both are null, return true.
136+ if (!bool (*this ) && !bool (other))
137+ return true ;
138+
139+ // Otherwise, check if the kinds match.
140+ if (getKind () != other.getKind ())
141+ return false ;
142+
143+ // Now that we know that the kinds match, perform the kind specific check.
144+ switch (getKind ()) {
145+ case Kind::Value:
146+ return getValue () == other.getValue ();
147+ case Kind::ActorAccessorInit:
148+ return true ;
149+ }
150+ }
151+
152+ bool operator !=(const ActorInstance &other) const {
153+ return !(*this == other);
154+ }
155+ };
156+
98157class SILIsolationInfo {
99158public:
100159 // / The lattice is:
@@ -122,18 +181,29 @@ class SILIsolationInfo {
122181
123182 // / If set this is the SILValue that represents the actor instance that we
124183 // / derived isolatedValue from.
125- SILValue actorInstance;
184+ // /
185+ // / If set to (SILValue(), 1), then we are in an
186+ ActorInstance actorInstance;
126187
127- SILIsolationInfo (ActorIsolation actorIsolation , SILValue isolatedValue ,
128- SILValue actorInstance )
188+ SILIsolationInfo (SILValue isolatedValue , SILValue actorInstance ,
189+ ActorIsolation actorIsolation )
129190 : kind(Actor), actorIsolation(actorIsolation),
130- isolatedValue (isolatedValue), actorInstance(actorInstance) {
191+ isolatedValue (isolatedValue),
192+ actorInstance(ActorInstance::getForValue(actorInstance)) {
131193 assert ((!actorInstance ||
132194 (actorIsolation.getKind () == ActorIsolation::ActorInstance &&
133195 actorInstance->getType ().isAnyActor ())) &&
134196 " actorInstance must be an actor if it is non-empty" );
135197 }
136198
199+ SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
200+ ActorIsolation actorIsolation)
201+ : kind(Actor), actorIsolation(actorIsolation),
202+ isolatedValue(isolatedValue), actorInstance(actorInstance) {
203+ assert (actorInstance);
204+ assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
205+ }
206+
137207 SILIsolationInfo (Kind kind, SILValue isolatedValue)
138208 : kind(kind), actorIsolation(), isolatedValue(isolatedValue) {}
139209
@@ -180,7 +250,7 @@ class SILIsolationInfo {
180250
181251 // / Return the specific SILValue for the actor that our isolated value is
182252 // / isolated to if one exists.
183- SILValue getActorInstance () const {
253+ ActorInstance getActorInstance () const {
184254 assert (kind == Actor);
185255 return actorInstance;
186256 }
@@ -193,37 +263,91 @@ class SILIsolationInfo {
193263
194264 [[nodiscard]] SILIsolationInfo merge (SILIsolationInfo other) const ;
195265
196- SILIsolationInfo withActorIsolated (SILValue isolatedValue,
197- SILValue actorInstance,
198- ActorIsolation isolation) {
199- return SILIsolationInfo::getActorIsolated (isolatedValue, actorInstance,
200- isolation);
201- }
202-
203266 static SILIsolationInfo getDisconnected () { return {Kind::Disconnected}; }
204267
205- static SILIsolationInfo getActorIsolated (SILValue isolatedValue,
206- SILValue actorInstance,
207- ActorIsolation actorIsolation) {
208- return {actorIsolation, isolatedValue, actorInstance};
209- }
210-
211- static SILIsolationInfo getActorIsolated (SILValue isolatedValue,
212- SILValue actorInstance,
213- NominalTypeDecl *typeDecl) {
214- if (typeDecl->isAnyActor ())
215- return {ActorIsolation::forActorInstanceSelf (typeDecl), isolatedValue,
216- actorInstance};
217- auto isolation = swift::getActorIsolation (typeDecl);
218- if (isolation.isGlobalActor ())
219- return {isolation, isolatedValue, actorInstance};
268+ // / Create an actor isolation for a value that we know is actor isolated to a
269+ // / specific actor, but we do not know the specific instance yet.
270+ // /
271+ // / This can occur when closing over a closure with an isolated parameter or
272+ // / if we are determining isolation of a function_ref that takes an isolated
273+ // / parameter. In both cases, we cannot know what the actual isolation is
274+ // / until we invoke the closure or function.
275+ // /
276+ // / TODO: This is just a stub currently until I implement the flow sensitive
277+ // / part. We just treat all instances the same. There are tests that validate
278+ // / this behavior.
279+ static SILIsolationInfo
280+ getFlowSensitiveActorIsolated (SILValue isolatedValue,
281+ ActorIsolation actorIsolation) {
282+ return {isolatedValue, SILValue (), actorIsolation};
283+ }
284+
285+ // / Only use this as a fallback if we cannot find better information.
286+ static SILIsolationInfo
287+ getWithIsolationCrossing (ApplyIsolationCrossing crossing) {
288+ if (crossing.getCalleeIsolation ().isActorIsolated ()) {
289+ // SIL level, just let it through
290+ return SILIsolationInfo (SILValue (), SILValue (),
291+ crossing.getCalleeIsolation ());
292+ }
293+
220294 return {};
221295 }
222296
297+ static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
298+ SILValue actorInstance,
299+ NominalTypeDecl *typeDecl) {
300+ assert (actorInstance);
301+ if (!typeDecl->isAnyActor ()) {
302+ assert (!swift::getActorIsolation (typeDecl).isGlobalActor () &&
303+ " Should have called getGlobalActorIsolated" );
304+ return {};
305+ }
306+ return {isolatedValue, actorInstance,
307+ ActorIsolation::forActorInstanceSelf (typeDecl)};
308+ }
309+
310+ static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
311+ ActorInstance actorInstance,
312+ NominalTypeDecl *typeDecl) {
313+ assert (actorInstance);
314+ if (!typeDecl->isAnyActor ()) {
315+ assert (!swift::getActorIsolation (typeDecl).isGlobalActor () &&
316+ " Should have called getGlobalActorIsolated" );
317+ return {};
318+ }
319+ return {isolatedValue, actorInstance,
320+ ActorIsolation::forActorInstanceSelf (typeDecl)};
321+ }
322+
323+ // / A special actor instance isolated for partial apply cases where we do not
324+ // / close over the isolated parameter and thus do not know the actual actor
325+ // / instance that we are going to use.
326+ static SILIsolationInfo
327+ getPartialApplyActorInstanceIsolated (SILValue isolatedValue,
328+ NominalTypeDecl *typeDecl) {
329+ if (!typeDecl->isAnyActor ()) {
330+ assert (!swift::getActorIsolation (typeDecl).isGlobalActor () &&
331+ " Should have called getGlobalActorIsolated" );
332+ return {};
333+ }
334+ return {isolatedValue, SILValue (),
335+ ActorIsolation::forActorInstanceSelf (typeDecl)};
336+ }
337+
223338 static SILIsolationInfo getGlobalActorIsolated (SILValue value,
224339 Type globalActorType) {
225- return getActorIsolated (value, SILValue () /* no actor instance*/ ,
226- ActorIsolation::forGlobalActor (globalActorType));
340+ return {value, SILValue () /* no actor instance*/ ,
341+ ActorIsolation::forGlobalActor (globalActorType)};
342+ }
343+
344+ static SILIsolationInfo getGlobalActorIsolated (SILValue value,
345+ ValueDecl *decl) {
346+ auto isolation = swift::getActorIsolation (decl);
347+ if (!isolation.isGlobalActor ())
348+ return {};
349+ return SILIsolationInfo::getGlobalActorIsolated (value,
350+ isolation.getGlobalActor ());
227351 }
228352
229353 static SILIsolationInfo getTaskIsolated (SILValue value) {
@@ -244,6 +368,18 @@ class SILIsolationInfo {
244368 return {};
245369 }
246370
371+ // / A helper that is used to ensure that we treat certain builtin values as
372+ // / non-Sendable that the AST level otherwise thinks are non-Sendable.
373+ // /
374+ // / E.x.: Builtin.RawPointer and Builtin.NativeObject
375+ // /
376+ // / TODO: Fix the type checker.
377+ static bool isNonSendableType (SILType type, SILFunction *fn);
378+
379+ static bool isNonSendableType (SILValue value) {
380+ return isNonSendableType (value->getType (), value->getFunction ());
381+ }
382+
247383 bool hasSameIsolation (ActorIsolation actorIsolation) const ;
248384
249385 // / Returns true if \p this and \p other have the same isolation. It allows
0 commit comments