Skip to content

Commit 7c5b1aa

Browse files
authored
Merge pull request #41967 from kavon/5.6-backtrack-defaultvalue-warning
🍒 [5.6] backtrack on part of SE-327 dealing with default-value exprs
2 parents ef7e22c + 5c37bff commit 7c5b1aa

File tree

6 files changed

+36
-91
lines changed

6 files changed

+36
-91
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4475,10 +4475,6 @@ ERROR(global_actor_from_nonactor_context,none,
44754475
"%0 %1 isolated to global actor %2 can not be %select{referenced|mutated|used 'inout'}4"
44764476
" from %select{this|a non-isolated}3%select{| synchronous}5 context",
44774477
(DescriptiveDeclKind, DeclName, Type, bool, unsigned, bool))
4478-
ERROR(global_actor_from_initializing_expr,none,
4479-
"expression requiring global actor %0 cannot appear in "
4480-
"default-value expression of %1 %2",
4481-
(Type, DescriptiveDeclKind, DeclName))
44824478
ERROR(actor_isolated_call,none,
44834479
"call to %0 function in a synchronous %1 context",
44844480
(ActorIsolation, ActorIsolation))

lib/AST/Decl.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8667,24 +8667,9 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
86678667
if (auto *vd = dyn_cast_or_null<ValueDecl>(dc->getAsDecl()))
86688668
return getActorIsolation(vd);
86698669

8670-
// In the context of the initializing or default-value expression of a
8671-
// stored property, the isolation varies between global and type members:
8672-
// - For a static stored property, the isolation matches the VarDecl.
8673-
// - For a field of a nominal type, the expression is not isolated.
8674-
// Without this distinction, a nominal can have non-async initializers
8675-
// with various kinds of isolation, so an impossible constraint can be
8676-
// created. See SE-0327 for details.
8677-
if (auto *var = dc->getNonLocalVarDecl()) {
8678-
8679-
// Isolation officially changes, as described above, in Swift 6+
8680-
if (dc->getASTContext().isSwiftVersionAtLeast(6) &&
8681-
var->isInstanceMember() &&
8682-
!var->getAttrs().hasAttribute<LazyAttr>()) {
8683-
return ActorIsolation::forUnspecified();
8684-
}
8685-
8670+
if (auto *var = dc->getNonLocalVarDecl())
86868671
return getActorIsolation(var);
8687-
}
8672+
86888673

86898674
if (auto *closure = dyn_cast<AbstractClosureExpr>(dc)) {
86908675
switch (auto isolation = closure->getActorIsolation()) {

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,57 +1299,6 @@ namespace {
12991299
return getDeclContext()->getParentModule();
13001300
}
13011301

1302-
/// In Swift 6, global-actor isolation is not carried-over to the
1303-
/// initializing expressions of non-static instance properties.
1304-
/// The actual change happens in \c getActorIsolationOfContext ,
1305-
/// but this function exists to warn users of Swift 5 about this
1306-
/// isolation change, so that they can prepare ahead-of-time.
1307-
void warnAboutGlobalActorIsoChangeInSwift6(const ActorIsolation &reqIso,
1308-
const Expr *user) {
1309-
if (ctx.isSwiftVersionAtLeast(6))
1310-
return;
1311-
1312-
// Check our context stack for a PatternBindingInitializer environment.
1313-
DeclContext const* withinDC = nullptr;
1314-
for (auto dc = contextStack.rbegin(); dc != contextStack.rend(); dc++) {
1315-
if (isa<PatternBindingInitializer>(*dc)) {
1316-
withinDC = *dc;
1317-
break;
1318-
}
1319-
}
1320-
1321-
// Not within a relevant decl context.
1322-
if (!withinDC)
1323-
return;
1324-
1325-
// Check if this PatternBindingInitializer's isolation would change
1326-
// in Swift 6+
1327-
if (auto *var = withinDC->getNonLocalVarDecl()) {
1328-
if (var->isInstanceMember() &&
1329-
!var->getAttrs().hasAttribute<LazyAttr>()) {
1330-
// At this point, we know the isolation will change in Swift 6.
1331-
// So, let's check if that change will cause an error.
1332-
1333-
auto dcIso = getActorIsolationOfContext(
1334-
const_cast<DeclContext*>(withinDC));
1335-
1336-
// If the isolation granted in Swift 5 is for a global actor, and
1337-
// the expression requires that global actor's isolation, then it will
1338-
// become an error in Swift 6.
1339-
if (dcIso.isGlobalActor() && dcIso == reqIso) {
1340-
ctx.Diags.diagnose(user->getLoc(),
1341-
diag::global_actor_from_initializing_expr,
1342-
reqIso.getGlobalActor(),
1343-
var->getDescriptiveKind(), var->getName())
1344-
.highlight(user->getSourceRange())
1345-
// make it a warning and attach the "this will become an error..."
1346-
// to the message. The error in Swift 6 will not be this diagnostic.
1347-
.warnUntilSwiftVersion(6);
1348-
}
1349-
}
1350-
}
1351-
}
1352-
13531302
/// Determine whether code in the given use context might execute
13541303
/// concurrently with code in the definition context.
13551304
bool mayExecuteConcurrentlyWith(
@@ -2192,12 +2141,8 @@ namespace {
21922141
// we are within that global actor already.
21932142
Optional<ActorIsolation> unsatisfiedIsolation;
21942143
if (Type globalActor = fnType->getGlobalActor()) {
2195-
if (getContextIsolation().isGlobalActor() &&
2196-
getContextIsolation().getGlobalActor()->isEqual(globalActor)) {
2197-
warnAboutGlobalActorIsoChangeInSwift6(
2198-
ActorIsolation::forGlobalActor(globalActor, false),
2199-
apply);
2200-
} else {
2144+
if (!(getContextIsolation().isGlobalActor() &&
2145+
getContextIsolation().getGlobalActor()->isEqual(globalActor))) {
22012146
unsatisfiedIsolation = ActorIsolation::forGlobalActor(
22022147
globalActor, /*unsafe=*/false);
22032148
}
@@ -2333,8 +2278,6 @@ namespace {
23332278
auto contextIsolation = getInnermostIsolatedContext(declContext);
23342279
if (contextIsolation.isGlobalActor() &&
23352280
contextIsolation.getGlobalActor()->isEqual(globalActor)) {
2336-
2337-
warnAboutGlobalActorIsoChangeInSwift6(contextIsolation, context);
23382281
return false;
23392282
}
23402283

test/Concurrency/global_actor_inference.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,9 @@ func replacesDynamicOnMainActor() {
587587
// ----------------------------------------------------------------------
588588

589589
class Cutter {
590-
@MainActor var x = useFooInADefer() // expected-warning {{expression requiring global actor 'MainActor' cannot appear in default-value expression of property 'x'; this is an error in Swift 6}}
590+
@MainActor var x = useFooInADefer()
591591
@MainActor var y = { () -> Bool in
592-
var z = statefulThingy // expected-warning {{expression requiring global actor 'MainActor' cannot appear in default-value expression of property 'y'; this is an error in Swift 6}}
592+
var z = statefulThingy
593593
return z
594594
}()
595595
}
@@ -601,7 +601,7 @@ class Butter {
601601
nonisolated let b = statefulThingy // expected-error {{var 'statefulThingy' isolated to global actor 'MainActor' can not be referenced from a non-isolated synchronous context}}
602602

603603
var c: Int = {
604-
return getGlobal7() // expected-warning {{expression requiring global actor 'SomeGlobalActor' cannot appear in default-value expression of property 'c'; this is an error in Swift 6}}
604+
return getGlobal7()
605605
}()
606606

607607
lazy var d: Int = getGlobal7()

test/Concurrency/property_initializers_swift6.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33

44
// REQUIRES: asserts
55

6-
@MainActor
7-
func mainActorFn() -> Int { return 0 } // expected-note 2 {{calls to global function 'mainActorFn()' from outside of its actor context are implicitly asynchronous}}
6+
@globalActor
7+
actor GlobalActor {
8+
static let shared = GlobalActor()
9+
}
10+
11+
@GlobalActor
12+
func globalActorFn() -> Int { return 0 } // expected-note {{calls to global function 'globalActorFn()' from outside of its actor context are implicitly asynchronous}}
813

9-
@MainActor
14+
@GlobalActor
1015
class C {
11-
var x: Int = mainActorFn() // expected-error {{call to main actor-isolated global function 'mainActorFn()' in a synchronous nonisolated context}}
16+
var x: Int = globalActorFn()
1217

13-
lazy var y: Int = mainActorFn()
18+
lazy var y: Int = globalActorFn()
1419

15-
static var z: Int = mainActorFn()
20+
static var z: Int = globalActorFn()
1621
}
1722

18-
@MainActor
19-
var x: Int = mainActorFn() // expected-error {{call to main actor-isolated global function 'mainActorFn()' in a synchronous nonisolated context}}
23+
var x: Int = globalActorFn() // expected-error {{call to global actor 'GlobalActor'-isolated global function 'globalActorFn()' in a synchronous nonisolated context}}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
2+
// REQUIRES: objc_interop
3+
// REQUIRES: OS=macosx
4+
5+
import SwiftUI
6+
7+
@MainActor
8+
class ContentState: ObservableObject { }
9+
10+
struct SomeView: View {
11+
@StateObject private var contentState = ContentState()
12+
13+
var body: some View {
14+
Text("Hello, world!")
15+
}
16+
}
17+

0 commit comments

Comments
 (0)