@@ -636,21 +636,14 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
636
636
if (cast<ValueDecl>(decl)->isLocalCapture ())
637
637
return forUnrestricted ();
638
638
639
- // 'let' declarations are immutable, so they can be accessed across
640
- // actors.
641
- bool isAccessibleAcrossActors = false ;
642
- if (auto var = dyn_cast<VarDecl>(decl)) {
643
- if (var->isLet ())
644
- isAccessibleAcrossActors = true ;
645
- }
646
-
647
639
// A function that provides an asynchronous context has no restrictions
648
640
// on its access.
649
641
//
650
642
// FIXME: technically, synchronous functions are allowed to be cross-actor.
651
643
// The call-sites are just conditionally async based on where they appear
652
644
// (outside or inside the actor). This suggests that the implicitly-async
653
645
// concept could be merged into the CrossActorSelf concept.
646
+ bool isAccessibleAcrossActors = false ;
654
647
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
655
648
if (func->isAsyncContext ())
656
649
isAccessibleAcrossActors = true ;
@@ -963,8 +956,7 @@ static bool diagnoseNonConcurrentProperty(
963
956
964
957
// / Whether we should diagnose cases where Sendable conformances are
965
958
// / missing.
966
- static bool shouldDiagnoseNonSendableViolations (
967
- const LangOptions &langOpts) {
959
+ bool swift::shouldDiagnoseNonSendableViolations (const LangOptions &langOpts) {
968
960
return langOpts.WarnConcurrency ;
969
961
}
970
962
@@ -1468,11 +1460,17 @@ namespace {
1468
1460
// was it an attempt to mutate an actor instance's isolated state?
1469
1461
} else if (auto environment = kindOfUsage (decl, context)) {
1470
1462
1471
- if (environment.getValue () == VarRefUseEnv::Read)
1463
+ if (isa<VarDecl>(decl) && cast<VarDecl>(decl)->isLet ()) {
1464
+ auto diag = decl->diagnose (diag::actor_isolated_let);
1465
+ SourceLoc fixItLoc =
1466
+ decl->getAttributeInsertionLoc (/* forModifier=*/ true );
1467
+ if (fixItLoc.isValid ())
1468
+ diag.fixItInsert (fixItLoc, " nonisolated " );
1469
+ } else if (environment.getValue () == VarRefUseEnv::Read) {
1472
1470
decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
1473
- else
1471
+ } else {
1474
1472
decl->diagnose (diag::actor_mutable_state, decl->getDescriptiveKind ());
1475
-
1473
+ }
1476
1474
} else {
1477
1475
decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
1478
1476
}
@@ -1645,11 +1643,6 @@ namespace {
1645
1643
1646
1644
// is it an access to a property?
1647
1645
if (isPropOrSubscript (decl)) {
1648
- // we assume let-bound properties are taken care of elsewhere,
1649
- // since they are never implicitly async.
1650
- assert (!isa<VarDecl>(decl) || cast<VarDecl>(decl)->isLet () == false
1651
- && " unexpected let-bound property; never implicitly async!" );
1652
-
1653
1646
if (auto declRef = dyn_cast_or_null<DeclRefExpr>(context)) {
1654
1647
if (usageEnv (declRef) == VarRefUseEnv::Read) {
1655
1648
@@ -1979,27 +1972,6 @@ namespace {
1979
1972
bool checkKeyPathExpr (KeyPathExpr *keyPath) {
1980
1973
bool diagnosed = false ;
1981
1974
1982
- // returns None if it is not a 'let'-bound var decl. Otherwise,
1983
- // the bool indicates whether a diagnostic was emitted.
1984
- auto checkLetBoundVarDecl = [&](KeyPathExpr::Component const & component)
1985
- -> Optional<bool > {
1986
- auto decl = component.getDeclRef ().getDecl ();
1987
- if (auto varDecl = dyn_cast<VarDecl>(decl)) {
1988
- if (varDecl->isLet ()) {
1989
- auto type = component.getComponentType ();
1990
- if (shouldDiagnoseNonSendableViolations (ctx.LangOpts )
1991
- && !isSendableType (getDeclContext (), type)) {
1992
- ctx.Diags .diagnose (
1993
- component.getLoc (), diag::non_concurrent_keypath_access,
1994
- type);
1995
- return true ;
1996
- }
1997
- return false ;
1998
- }
1999
- }
2000
- return None;
2001
- };
2002
-
2003
1975
// check the components of the keypath.
2004
1976
for (const auto &component : keyPath->getComponents ()) {
2005
1977
// The decl referred to by the path component cannot be within an actor.
@@ -2027,13 +1999,6 @@ namespace {
2027
1999
LLVM_FALLTHROUGH; // otherwise, it's invalid so diagnose it.
2028
2000
2029
2001
case ActorIsolationRestriction::CrossActorSelf:
2030
- // 'let'-bound decls with this isolation are OK, just check them.
2031
- if (auto wasLetBound = checkLetBoundVarDecl (component)) {
2032
- diagnosed = wasLetBound.getValue ();
2033
- break ;
2034
- }
2035
- LLVM_FALLTHROUGH; // otherwise, it's invalid so diagnose it.
2036
-
2037
2002
case ActorIsolationRestriction::ActorSelf: {
2038
2003
auto decl = concDecl.getDecl ();
2039
2004
ctx.Diags .diagnose (component.getLoc (),
0 commit comments