Skip to content

Commit 9b1fced

Browse files
committed
backtrack on part of SE-327 dealing with default-value exprs
This effectively reverts 6823744 The blanket removal of isolation in default-value expressions had unintented consequences for important workflows. It's still a problem that needs to be addressed, but we need to be more precise about the problematic situations.
1 parent 552d4b0 commit 9b1fced

File tree

6 files changed

+26
-85
lines changed

6 files changed

+26
-85
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,10 +4555,6 @@ ERROR(global_actor_from_nonactor_context,none,
45554555
"%0 %1 isolated to global actor %2 can not be %select{referenced|mutated|used 'inout'}4"
45564556
" from %select{this|a non-isolated}3%select{| synchronous}5 context",
45574557
(DescriptiveDeclKind, DeclName, Type, bool, unsigned, bool))
4558-
ERROR(global_actor_from_initializing_expr,none,
4559-
"expression requiring global actor %0 cannot appear in "
4560-
"default-value expression of %1 %2",
4561-
(Type, DescriptiveDeclKind, DeclName))
45624558
ERROR(actor_isolated_call,none,
45634559
"call to %0 function in a synchronous %1 context",
45644560
(ActorIsolation, ActorIsolation))

lib/AST/Decl.cpp

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

9047-
// In the context of the initializing or default-value expression of a
9048-
// stored property, the isolation varies between global and type members:
9049-
// - For a static stored property, the isolation matches the VarDecl.
9050-
// - For a field of a nominal type, the expression is not isolated.
9051-
// Without this distinction, a nominal can have non-async initializers
9052-
// with various kinds of isolation, so an impossible constraint can be
9053-
// created. See SE-0327 for details.
9054-
if (auto *var = dc->getNonLocalVarDecl()) {
9055-
9056-
// Isolation officially changes, as described above, in Swift 6+
9057-
if (dc->getASTContext().isSwiftVersionAtLeast(6) &&
9058-
var->isInstanceMember() &&
9059-
!var->getAttrs().hasAttribute<LazyAttr>()) {
9060-
return ActorIsolation::forUnspecified();
9061-
}
9062-
9047+
if (auto *var = dc->getNonLocalVarDecl())
90639048
return getActorIsolation(var);
9064-
}
9049+
90659050

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

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,57 +1396,6 @@ namespace {
13961396
return getDeclContext()->getParentModule();
13971397
}
13981398

1399-
/// In Swift 6, global-actor isolation is not carried-over to the
1400-
/// initializing expressions of non-static instance properties.
1401-
/// The actual change happens in \c getActorIsolationOfContext ,
1402-
/// but this function exists to warn users of Swift 5 about this
1403-
/// isolation change, so that they can prepare ahead-of-time.
1404-
void warnAboutGlobalActorIsoChangeInSwift6(const ActorIsolation &reqIso,
1405-
const Expr *user) {
1406-
if (ctx.isSwiftVersionAtLeast(6))
1407-
return;
1408-
1409-
// Check our context stack for a PatternBindingInitializer environment.
1410-
DeclContext const* withinDC = nullptr;
1411-
for (auto dc = contextStack.rbegin(); dc != contextStack.rend(); dc++) {
1412-
if (isa<PatternBindingInitializer>(*dc)) {
1413-
withinDC = *dc;
1414-
break;
1415-
}
1416-
}
1417-
1418-
// Not within a relevant decl context.
1419-
if (!withinDC)
1420-
return;
1421-
1422-
// Check if this PatternBindingInitializer's isolation would change
1423-
// in Swift 6+
1424-
if (auto *var = withinDC->getNonLocalVarDecl()) {
1425-
if (var->isInstanceMember() &&
1426-
!var->getAttrs().hasAttribute<LazyAttr>()) {
1427-
// At this point, we know the isolation will change in Swift 6.
1428-
// So, let's check if that change will cause an error.
1429-
1430-
auto dcIso = getActorIsolationOfContext(
1431-
const_cast<DeclContext*>(withinDC));
1432-
1433-
// If the isolation granted in Swift 5 is for a global actor, and
1434-
// the expression requires that global actor's isolation, then it will
1435-
// become an error in Swift 6.
1436-
if (dcIso.isGlobalActor() && dcIso == reqIso) {
1437-
ctx.Diags.diagnose(user->getLoc(),
1438-
diag::global_actor_from_initializing_expr,
1439-
reqIso.getGlobalActor(),
1440-
var->getDescriptiveKind(), var->getName())
1441-
.highlight(user->getSourceRange())
1442-
// make it a warning and attach the "this will become an error..."
1443-
// to the message. The error in Swift 6 will not be this diagnostic.
1444-
.warnUntilSwiftVersion(6);
1445-
}
1446-
}
1447-
}
1448-
}
1449-
14501399
/// Determine whether code in the given use context might execute
14511400
/// concurrently with code in the definition context.
14521401
bool mayExecuteConcurrentlyWith(
@@ -2341,12 +2290,8 @@ namespace {
23412290
// we are within that global actor already.
23422291
Optional<ActorIsolation> unsatisfiedIsolation;
23432292
if (Type globalActor = fnType->getGlobalActor()) {
2344-
if (getContextIsolation().isGlobalActor() &&
2345-
getContextIsolation().getGlobalActor()->isEqual(globalActor)) {
2346-
warnAboutGlobalActorIsoChangeInSwift6(
2347-
ActorIsolation::forGlobalActor(globalActor, false),
2348-
apply);
2349-
} else {
2293+
if (!(getContextIsolation().isGlobalActor() &&
2294+
getContextIsolation().getGlobalActor()->isEqual(globalActor))) {
23502295
unsatisfiedIsolation = ActorIsolation::forGlobalActor(
23512296
globalActor, /*unsafe=*/false);
23522297
}
@@ -2483,8 +2428,6 @@ namespace {
24832428
auto contextIsolation = getInnermostIsolatedContext(declContext);
24842429
if (contextIsolation.isGlobalActor() &&
24852430
contextIsolation.getGlobalActor()->isEqual(globalActor)) {
2486-
2487-
warnAboutGlobalActorIsoChangeInSwift6(contextIsolation, context);
24882431
return false;
24892432
}
24902433

test/Concurrency/global_actor_inference.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,9 +623,9 @@ func replacesDynamicOnMainActor() {
623623
// ----------------------------------------------------------------------
624624

625625
class Cutter {
626-
@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}}
626+
@MainActor var x = useFooInADefer()
627627
@MainActor var y = { () -> Bool in
628-
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}}
628+
var z = statefulThingy
629629
return z
630630
}()
631631
}
@@ -637,7 +637,7 @@ class Butter {
637637
nonisolated let b = statefulThingy // expected-error {{var 'statefulThingy' isolated to global actor 'MainActor' can not be referenced from a non-isolated synchronous context}}
638638

639639
var c: Int = {
640-
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}}
640+
return getGlobal7()
641641
}()
642642

643643
lazy var d: Int = getGlobal7()

test/Concurrency/property_initializers_swift6.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ actor GlobalActor {
99
}
1010

1111
@GlobalActor
12-
func globalActorFn() -> Int { return 0 } // expected-note 2 {{calls to global function 'globalActorFn()' from outside of its actor context are implicitly asynchronous}}
12+
func globalActorFn() -> Int { return 0 } // expected-note {{calls to global function 'globalActorFn()' from outside of its actor context are implicitly asynchronous}}
1313

1414
@GlobalActor
1515
class C {
16-
var x: Int = globalActorFn() // expected-error {{call to global actor 'GlobalActor'-isolated global function 'globalActorFn()' in a synchronous nonisolated context}}
16+
var x: Int = globalActorFn()
1717

1818
lazy var y: Int = globalActorFn()
1919

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)