Skip to content

Commit a78f259

Browse files
authored
Merge pull request #4350 from swiftwasm/main
[pull] swiftwasm from main
2 parents 0f8e6cc + 6c829e0 commit a78f259

File tree

8 files changed

+212
-47
lines changed

8 files changed

+212
-47
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,36 @@ static bool checkClassGlobalActorIsolation(
36083608
return true;
36093609
}
36103610

3611+
/// Generally speaking, the isolation of the decl that overrides
3612+
/// must match the overridden decl. But there are a number of exceptions,
3613+
/// e.g., the decl that overrides can be nonisolated.
3614+
/// \param newIso the isolation of the overriding declaration.
3615+
static bool validOverrideIsolation(ActorIsolation newIso,
3616+
ValueDecl *overriddenDecl,
3617+
ActorIsolation overriddenIso) {
3618+
// If the isolation matches, we're done.
3619+
if (newIso == overriddenIso)
3620+
return true;
3621+
3622+
// If the overriding declaration is non-isolated, it's okay.
3623+
if (newIso.isIndependent() || newIso.isUnspecified())
3624+
return true;
3625+
3626+
// If both are actor-instance isolated, we're done. This wasn't caught by
3627+
// the equality case above because the nominal type describing the actor
3628+
// will differ when we're overriding.
3629+
if (newIso.getKind() == overriddenIso.getKind() &&
3630+
newIso.getKind() == ActorIsolation::ActorInstance)
3631+
return true;
3632+
3633+
// If the overridden declaration is from Objective-C with no actor annotation,
3634+
// allow it.
3635+
if (overriddenDecl->hasClangNode() && !overriddenIso)
3636+
return true;
3637+
3638+
return false;
3639+
}
3640+
36113641
ActorIsolation ActorIsolationRequest::evaluate(
36123642
Evaluator &evaluator, ValueDecl *value) const {
36133643
// If this declaration has actor-isolated "self", it's isolated to that
@@ -3665,9 +3695,36 @@ ActorIsolation ActorIsolationRequest::evaluate(
36653695
if (!ctor->hasAsync())
36663696
defaultIsolation = ActorIsolation::forIndependent();
36673697

3698+
// Look for and remember the overridden declaration's isolation.
3699+
Optional<ActorIsolation> overriddenIso;
3700+
ValueDecl *overriddenValue = nullptr;
3701+
if ( (overriddenValue = value->getOverriddenDecl()) ) {
3702+
auto iso = getActorIsolation(overriddenValue);
3703+
SubstitutionMap subs;
3704+
3705+
if (Type selfType = value->getDeclContext()->getSelfInterfaceType()) {
3706+
subs = selfType->getMemberSubstitutionMap(
3707+
value->getModuleContext(), overriddenValue);
3708+
}
3709+
iso = iso.subst(subs);
3710+
3711+
// use the overridden decl's iso as the default isolation for this decl.
3712+
defaultIsolation = iso;
3713+
overriddenIso = iso;
3714+
}
3715+
36683716
// Function used when returning an inferred isolation.
36693717
auto inferredIsolation = [&](
36703718
ActorIsolation inferred, bool onlyGlobal = false) {
3719+
// check if the inferred isolation is valid in the context of
3720+
// its overridden isolation.
3721+
if (overriddenValue) {
3722+
// if the inferred isolation is not valid, then carry-over the overridden
3723+
// declaration's isolation as this decl's inferred isolation.
3724+
if (!validOverrideIsolation(inferred, overriddenValue, *overriddenIso))
3725+
inferred = *overriddenIso;
3726+
}
3727+
36713728
// Add an implicit attribute to capture the actor isolation that was
36723729
// inferred, so that (e.g.) it will be printed and serialized.
36733730
ASTContext &ctx = value->getASTContext();
@@ -3754,20 +3811,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
37543811
}
37553812
}
37563813

3757-
// If the declaration overrides another declaration, it must have the same
3758-
// actor isolation.
3759-
if (auto overriddenValue = value->getOverriddenDecl()) {
3760-
auto isolation = getActorIsolation(overriddenValue);
3761-
SubstitutionMap subs;
3762-
3763-
if (Type selfType = value->getDeclContext()->getSelfInterfaceType()) {
3764-
subs = selfType->getMemberSubstitutionMap(
3765-
value->getModuleContext(), overriddenValue);
3766-
}
3767-
3768-
return inferredIsolation(isolation.subst(subs));
3769-
}
3770-
37713814
// If this is an accessor, use the actor isolation of its storage
37723815
// declaration.
37733816
if (auto accessor = dyn_cast<AccessorDecl>(value)) {
@@ -3962,30 +4005,7 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
39624005
overriddenIsolation = overriddenIsolation.subst(subs);
39634006
}
39644007

3965-
// If the isolation matches, we're done.
3966-
if (isolation == overriddenIsolation)
3967-
return;
3968-
3969-
// FIXME: do we need this?
3970-
if (overriddenIsolation == ActorIsolation::Unspecified &&
3971-
isolation == ActorIsolation::Independent) {
3972-
return;
3973-
}
3974-
3975-
// If the overriding declaration is non-isolated, it's okay.
3976-
if (isolation.isIndependent() || isolation.isUnspecified())
3977-
return;
3978-
3979-
// If both are actor-instance isolated, we're done. This wasn't caught by
3980-
// the equality case above because the nominal type describing the actor
3981-
// will differ when we're overriding.
3982-
if (isolation.getKind() == overriddenIsolation.getKind() &&
3983-
isolation.getKind() == ActorIsolation::ActorInstance)
3984-
return;
3985-
3986-
// If the overridden declaration is from Objective-C with no actor annotation,
3987-
// allow it.
3988-
if (overridden->hasClangNode() && !overriddenIsolation)
4008+
if (validOverrideIsolation(isolation, overridden, overriddenIsolation))
39894009
return;
39904010

39914011
// Isolation mismatch. Diagnose it.

stdlib/public/Platform/visualc.modulemap

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,24 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
module visualc [system] {
14-
export *
15-
1614
module SAL {
1715
header "sal.h"
16+
export *
1817
}
1918

2019
module vcruntime {
2120
header "vcruntime.h"
22-
export SAL
21+
export *
2322
}
2423

2524
module setjmp {
2625
header "setjmp.h"
26+
export *
2727
}
2828

2929
module stdint {
3030
header "stdint.h"
31+
export *
3132
}
3233
}
3334

stdlib/public/SwiftShims/SwiftStdint.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
// Clang has been defining __INTxx_TYPE__ macros for a long time.
2626
// __UINTxx_TYPE__ are defined only since Clang 3.5.
27-
#if !defined(__APPLE__) && (defined(_MSC_VER) && !defined(__clang__)) && !defined(__linux__) && !defined(__OpenBSD__)
27+
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__OpenBSD__)
2828
#include <stdint.h>
2929
typedef int64_t __swift_int64_t;
3030
typedef uint64_t __swift_uint64_t;

stdlib/public/core/CollectionAlgorithms.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ extension MutableCollection where Self: RandomAccessCollection {
553553
/// Use the `shuffle()` method to randomly reorder the elements of an array.
554554
///
555555
/// var names = ["Alejandro", "Camila", "Diego", "Luciana", "Luis", "Sofía"]
556-
/// names.shuffle(using: myGenerator)
556+
/// names.shuffle()
557557
/// // names == ["Luis", "Camila", "Luciana", "Sofía", "Alejandro", "Diego"]
558558
///
559559
/// This method is equivalent to calling `shuffle(using:)`, passing in the

test/ClangImporter/objc_async.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,69 @@ func testMirrored(instance: ClassWithAsync) async {
230230
func g() async { }
231231
}
232232

233+
234+
@MainActor func mainActorFn() {}
235+
@SomeGlobalActor func sgActorFn() {}
236+
237+
// Check inferred isolation for overridden decls from ObjC.
238+
// Note that even if the override is not present, it
239+
// can have an affect. -- rdar://87217618 / SR-15694
240+
@MainActor
241+
class FooFrame: PictureFrame {
242+
init() {
243+
super.init(size: 0)
244+
}
245+
246+
override init(size n: Int) {
247+
super.init(size: n)
248+
}
249+
250+
override func rotate() {
251+
mainActorFn()
252+
}
253+
}
254+
255+
class BarFrame: PictureFrame {
256+
init() {
257+
super.init(size: 0)
258+
}
259+
260+
override init(size n: Int) {
261+
super.init(size: n)
262+
}
263+
264+
override func rotate() {
265+
mainActorFn()
266+
}
267+
}
268+
269+
@SomeGlobalActor
270+
class BazFrame: NotIsolatedPictureFrame {
271+
init() {
272+
super.init(size: 0)
273+
}
274+
275+
override init(size n: Int) {
276+
super.init(size: n)
277+
}
278+
279+
override func rotate() {
280+
sgActorFn()
281+
}
282+
}
283+
284+
@SomeGlobalActor
285+
class BazFrameIso: PictureFrame { // expected-error {{global actor 'SomeGlobalActor'-isolated class 'BazFrameIso' has different actor isolation from main actor-isolated superclass 'PictureFrame'}}
286+
}
287+
288+
func check() async {
289+
_ = await BarFrame()
290+
_ = await FooFrame()
291+
_ = await BazFrame()
292+
293+
_ = await BarFrame(size: 0)
294+
_ = await FooFrame(size: 0)
295+
_ = await BazFrame(size: 0)
296+
}
297+
233298
} // SwiftStdlib 5.5

test/Concurrency/actor_isolation.swift

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,11 @@ struct GenericGlobalActor<T> {
403403
}
404404

405405
@available(SwiftStdlib 5.1, *)
406-
@SomeGlobalActor func onions() {} // expected-note{{calls to global function 'onions()' from outside of its actor context are implicitly asynchronous}}
406+
@SomeGlobalActor func onions_sga() {} // expected-note 2{{calls to global function 'onions_sga()' from outside of its actor context are implicitly asynchronous}}
407407

408408
@available(SwiftStdlib 5.1, *)
409-
@MainActor func beets() { onions() } // expected-error{{call to global actor 'SomeGlobalActor'-isolated global function 'onions()' in a synchronous main actor-isolated context}}
410-
// expected-note@-1{{calls to global function 'beets()' from outside of its actor context are implicitly asynchronous}}
409+
@MainActor func beets_ma() { onions_sga() } // expected-error{{call to global actor 'SomeGlobalActor'-isolated global function 'onions_sga()' in a synchronous main actor-isolated context}}
410+
// expected-note@-1 4{{calls to global function 'beets_ma()' from outside of its actor context are implicitly asynchronous}}
411411

412412
@available(SwiftStdlib 5.1, *)
413413
actor Crystal {
@@ -942,7 +942,7 @@ class SomeClassWithInits {
942942
deinit {
943943
print(mutableState) // Okay, we're actor-isolated
944944
print(SomeClassWithInits.shared) // expected-error{{static property 'shared' isolated to global actor 'MainActor' can not be referenced from this synchronous context}}
945-
beets() //expected-error{{call to main actor-isolated global function 'beets()' in a synchronous nonisolated context}}
945+
beets_ma() //expected-error{{call to main actor-isolated global function 'beets_ma()' in a synchronous nonisolated context}}
946946
}
947947

948948
func isolated() { }
@@ -1384,3 +1384,68 @@ actor DunkTracker {
13841384
}
13851385
}
13861386
}
1387+
1388+
@MainActor
1389+
class MA {
1390+
func method() {}
1391+
}
1392+
1393+
@SomeGlobalActor class SGA: MA {} // expected-error {{global actor 'SomeGlobalActor'-isolated class 'SGA' has different actor isolation from main actor-isolated superclass 'MA'}}
1394+
1395+
protocol SGA_Proto {
1396+
@SomeGlobalActor func method() // expected-note {{'method()' declared here}}
1397+
}
1398+
1399+
// try to override a MA method with inferred isolation from a protocol requirement
1400+
class SGA_MA: MA, SGA_Proto {
1401+
// expected-error@+2 {{call to global actor 'SomeGlobalActor'-isolated global function 'onions_sga()' in a synchronous main actor-isolated context}}
1402+
// expected-warning@+1 {{instance method 'method()' isolated to global actor 'MainActor' can not satisfy corresponding requirement from protocol 'SGA_Proto' isolated to global actor 'SomeGlobalActor'}}
1403+
override func method() { onions_sga() }
1404+
}
1405+
1406+
class None_MA: MA {
1407+
override func method() { beets_ma() }
1408+
}
1409+
1410+
class None {
1411+
func method() {} // expected-note{{overridden declaration is here}}
1412+
}
1413+
1414+
// try to add inferred isolation while overriding
1415+
@MainActor
1416+
class MA_None1: None {
1417+
// FIXME: bad note, since the problem is a mismatch in overridden vs inferred isolation; this wont help.
1418+
// expected-note@+1 {{add '@MainActor' to make instance method 'method()' part of global actor 'MainActor'}}
1419+
override func method() {
1420+
beets_ma() // expected-error {{call to main actor-isolated global function 'beets_ma()' in a synchronous nonisolated context}}
1421+
}
1422+
}
1423+
1424+
class MA_None2: None {
1425+
@MainActor
1426+
override func method() { // expected-error {{main actor-isolated instance method 'method()' has different actor isolation from nonisolated overridden declaration}}
1427+
beets_ma()
1428+
}
1429+
}
1430+
1431+
class MADirect {
1432+
@MainActor func method1() {}
1433+
@MainActor func method2() {}
1434+
}
1435+
1436+
class None_MADirect: MADirect {
1437+
// default-isolation vs overridden-MainActor = mainactor
1438+
override func method1() { beets_ma() }
1439+
1440+
// directly-nonisolated vs overridden mainactor = nonisolated
1441+
nonisolated override func method2() { beets_ma() } // expected-error {{call to main actor-isolated global function 'beets_ma()' in a synchronous nonisolated context}}
1442+
}
1443+
1444+
@SomeGlobalActor
1445+
class SGA_MADirect: MADirect {
1446+
// inferred-SomeGlobalActor vs overridden-MainActor = mainactor
1447+
override func method1() { beets_ma() }
1448+
1449+
// directly-nonisolated vs overridden-MainActor = nonisolated
1450+
nonisolated override func method2() { beets_ma() } // expected-error {{call to main actor-isolated global function 'beets_ma()' in a synchronous nonisolated context}}
1451+
}

test/Incremental/Verifier/single-file-private/AnyObject.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ import Foundation
8080
// expected-member {{ObjectiveC.NSObject.Hasher}}
8181
// expected-member {{ObjectiveC.NSObjectProtocol.hash}}
8282

83+
// expected-member {{Swift.Hashable.init}}
8384
// expected-member {{Swift.Hashable.deinit}}
85+
// expected-member {{Swift.Equatable.init}}
8486
// expected-member {{Swift.Equatable.deinit}}
8587

8688
// expected-member {{Swift.Hashable.==}}

test/Inputs/clang-importer-sdk/usr/include/ObjCConcurrency.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma clang assume_nonnull begin
55

66
#define MAIN_ACTOR __attribute__((__swift_attr__("@MainActor")))
7+
#define UI_ACTOR __attribute__((swift_attr("@UIActor")))
78

89
#ifdef __SWIFT_ATTR_SUPPORTS_SENDABLE_DECLS
910
#define SENDABLE __attribute__((__swift_attr__("@Sendable")))
@@ -247,6 +248,17 @@ typedef NS_ERROR_ENUM(unsigned, NonSendableErrorCode, NonSendableErrorDomain) {
247248
} NONSENDABLE;
248249
// expected-warning@-3 {{cannot make error code type 'NonSendableErrorCode' non-sendable because Swift errors are always sendable}}
249250

251+
UI_ACTOR
252+
@interface PictureFrame : NSObject
253+
- (instancetype)initWithSize:(NSInteger)frame NS_DESIGNATED_INITIALIZER;
254+
- (void)rotate;
255+
@end
256+
257+
@interface NotIsolatedPictureFrame : NSObject
258+
- (instancetype)initWithSize:(NSInteger)frame NS_DESIGNATED_INITIALIZER;
259+
- (void)rotate;
260+
@end
261+
250262
typedef NSString *SendableStringEnum NS_STRING_ENUM;
251263
typedef NSString *NonSendableStringEnum NS_STRING_ENUM NONSENDABLE;
252264

0 commit comments

Comments
 (0)