@@ -636,21 +636,14 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
636636 if (cast<ValueDecl>(decl)->isLocalCapture ())
637637 return forUnrestricted ();
638638
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-
647639 // A function that provides an asynchronous context has no restrictions
648640 // on its access.
649641 //
650642 // FIXME: technically, synchronous functions are allowed to be cross-actor.
651643 // The call-sites are just conditionally async based on where they appear
652644 // (outside or inside the actor). This suggests that the implicitly-async
653645 // concept could be merged into the CrossActorSelf concept.
646+ bool isAccessibleAcrossActors = false ;
654647 if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
655648 if (func->isAsyncContext ())
656649 isAccessibleAcrossActors = true ;
@@ -963,8 +956,7 @@ static bool diagnoseNonConcurrentProperty(
963956
964957// / Whether we should diagnose cases where Sendable conformances are
965958// / missing.
966- static bool shouldDiagnoseNonSendableViolations (
967- const LangOptions &langOpts) {
959+ bool swift::shouldDiagnoseNonSendableViolations (const LangOptions &langOpts) {
968960 return langOpts.WarnConcurrency ;
969961}
970962
@@ -1468,11 +1460,17 @@ namespace {
14681460 // was it an attempt to mutate an actor instance's isolated state?
14691461 } else if (auto environment = kindOfUsage (decl, context)) {
14701462
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) {
14721470 decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
1473- else
1471+ } else {
14741472 decl->diagnose (diag::actor_mutable_state, decl->getDescriptiveKind ());
1475-
1473+ }
14761474 } else {
14771475 decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
14781476 }
@@ -1645,11 +1643,6 @@ namespace {
16451643
16461644 // is it an access to a property?
16471645 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-
16531646 if (auto declRef = dyn_cast_or_null<DeclRefExpr>(context)) {
16541647 if (usageEnv (declRef) == VarRefUseEnv::Read) {
16551648
@@ -1979,27 +1972,6 @@ namespace {
19791972 bool checkKeyPathExpr (KeyPathExpr *keyPath) {
19801973 bool diagnosed = false ;
19811974
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-
20031975 // check the components of the keypath.
20041976 for (const auto &component : keyPath->getComponents ()) {
20051977 // The decl referred to by the path component cannot be within an actor.
@@ -2027,13 +1999,6 @@ namespace {
20271999 LLVM_FALLTHROUGH; // otherwise, it's invalid so diagnose it.
20282000
20292001 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-
20372002 case ActorIsolationRestriction::ActorSelf: {
20382003 auto decl = concDecl.getDecl ();
20392004 ctx.Diags .diagnose (component.getLoc (),
0 commit comments