@@ -9383,7 +9383,18 @@ void ParamDecl::setDefaultExpr(Expr *E) {
9383
9383
}
9384
9384
9385
9385
void ParamDecl::setTypeCheckedDefaultExpr (Expr *E) {
9386
- assert (E || getDefaultArgumentKind () == DefaultArgumentKind::Inherited);
9386
+ // The type-checker will only produce a null expression here if the
9387
+ // default argument is inherited, so if we're called with a null pointer
9388
+ // in any other case, it must be from a request cycle. Don't crash;
9389
+ // just wrap the original expression with an ErrorExpr and proceed.
9390
+ if (!E && getDefaultArgumentKind () != DefaultArgumentKind::Inherited) {
9391
+ auto *initExpr = getStructuralDefaultExpr ();
9392
+ assert (initExpr);
9393
+ auto &ctx = getASTContext ();
9394
+ E = new (ctx) ErrorExpr (initExpr->getSourceRange (), ErrorType::get (ctx),
9395
+ initExpr);
9396
+ }
9397
+
9387
9398
setDefaultExpr (E);
9388
9399
9389
9400
auto *defaultInfo = DefaultValueAndFlags.getPointer ();
@@ -11808,6 +11819,12 @@ PrecedenceGroupDecl *InfixOperatorDecl::getPrecedenceGroup() const {
11808
11819
nullptr );
11809
11820
}
11810
11821
11822
+ bool ValueDecl::isDeferBody () const {
11823
+ if (auto fn = dyn_cast<FuncDecl>(this ))
11824
+ return fn->isDeferBody ();
11825
+ return false ;
11826
+ }
11827
+
11811
11828
bool FuncDecl::isDeferBody () const {
11812
11829
return getBaseIdentifier () == getASTContext ().getIdentifier (" $defer" );
11813
11830
}
@@ -11999,55 +12016,93 @@ ActorIsolation swift::getActorIsolationOfContext(
11999
12016
DeclContext *dc,
12000
12017
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
12001
12018
getClosureActorIsolation) {
12002
- auto &ctx = dc->getASTContext ();
12003
12019
auto dcToUse = dc;
12004
- // Defer bodies share actor isolation of their enclosing context.
12005
- if (auto FD = dyn_cast<FuncDecl>(dcToUse)) {
12006
- if (FD->isDeferBody ()) {
12007
- dcToUse = FD->getDeclContext ();
12008
- }
12020
+
12021
+ // Defer bodies share the actor isolation of their enclosing context.
12022
+ // We don't actually have to do this check here because
12023
+ // getActorIsolation does consider it already, but it's nice to
12024
+ // avoid some extra request evaluation in a trivial case.
12025
+ while (auto FD = dyn_cast<FuncDecl>(dcToUse)) {
12026
+ if (!FD->isDeferBody ()) break ;
12027
+ dcToUse = FD->getDeclContext ();
12009
12028
}
12029
+
12010
12030
if (auto *vd = dyn_cast_or_null<ValueDecl>(dcToUse->getAsDecl ()))
12011
12031
return getActorIsolation (vd);
12012
12032
12013
- // In the context of the initializing or default-value expression of a
12014
- // stored property:
12015
- // - For a static stored property, the isolation matches the VarDecl.
12016
- // Static properties are initialized upon first use, so the isolation
12017
- // of the initializer must match the isolation required to access the
12018
- // property.
12019
- // - For a field of a nominal type, the expression can require the same
12020
- // actor isolation as the field itself. That default expression may only
12021
- // be used from inits that meet the required isolation.
12022
- if (auto *var = dcToUse->getNonLocalVarDecl ()) {
12023
- // If IsolatedDefaultValues are enabled, treat this context as having
12024
- // unspecified isolation. We'll compute the required isolation for
12025
- // the initializer and validate that it matches the isolation of the
12026
- // var itself in the DefaultInitializerIsolation request.
12027
- if (ctx.LangOpts .hasFeature (Feature::IsolatedDefaultValues))
12028
- return ActorIsolation::forUnspecified ();
12029
-
12030
- return getActorIsolation (var);
12031
- }
12032
-
12033
12033
if (auto *closure = dyn_cast<AbstractClosureExpr>(dcToUse)) {
12034
12034
return getClosureActorIsolation (closure);
12035
12035
}
12036
12036
12037
+ if (auto *init = dyn_cast<Initializer>(dcToUse)) {
12038
+ // FIXME: force default argument initializers to report a meaningless
12039
+ // isolation in order to break a bunch of cycles with the way that
12040
+ // isolation is computed for them.
12041
+ return getActorIsolation (init, /* ignoreDefaultArguments*/ true );
12042
+ }
12043
+
12037
12044
if (isa<TopLevelCodeDecl>(dcToUse)) {
12045
+ auto &ctx = dc->getASTContext ();
12038
12046
if (dcToUse->isAsyncContext () ||
12039
- dcToUse->getASTContext ().LangOpts .StrictConcurrencyLevel >=
12040
- StrictConcurrency::Complete) {
12041
- if (Type mainActor = dcToUse->getASTContext ().getMainActorType ())
12047
+ ctx.LangOpts .StrictConcurrencyLevel >= StrictConcurrency::Complete) {
12048
+ if (Type mainActor = ctx.getMainActorType ())
12042
12049
return ActorIsolation::forGlobalActor (mainActor)
12043
- .withPreconcurrency (
12044
- !dcToUse->getASTContext ().isSwiftVersionAtLeast (6 ));
12050
+ .withPreconcurrency (!ctx.isSwiftVersionAtLeast (6 ));
12045
12051
}
12046
12052
}
12047
12053
12048
12054
return ActorIsolation::forUnspecified ();
12049
12055
}
12050
12056
12057
+ ActorIsolation swift::getActorIsolation (Initializer *init,
12058
+ bool ignoreDefaultArguments) {
12059
+ switch (init->getInitializerKind ()) {
12060
+ case InitializerKind::PatternBinding:
12061
+ // In the context of the initializing or default-value expression of a
12062
+ // stored property:
12063
+ // - For a static stored property, the isolation matches the VarDecl.
12064
+ // Static properties are initialized upon first use, so the isolation
12065
+ // of the initializer must match the isolation required to access the
12066
+ // property.
12067
+ // - For a field of a nominal type, the expression can require the same
12068
+ // actor isolation as the field itself. That default expression may only
12069
+ // be used from inits that meet the required isolation.
12070
+ if (auto *var = init->getNonLocalVarDecl ()) {
12071
+ auto &ctx = var->getASTContext ();
12072
+
12073
+ // If IsolatedDefaultValues are enabled, treat this context as having
12074
+ // unspecified isolation. We'll compute the required isolation for
12075
+ // the initializer and validate that it matches the isolation of the
12076
+ // var itself in the DefaultInitializerIsolation request.
12077
+ if (ctx.LangOpts .hasFeature (Feature::IsolatedDefaultValues))
12078
+ return ActorIsolation::forUnspecified ();
12079
+
12080
+ return getActorIsolation (var);
12081
+ }
12082
+
12083
+ return ActorIsolation::forUnspecified ();
12084
+
12085
+ case InitializerKind::DefaultArgument: {
12086
+ auto defArgInit = cast<DefaultArgumentInitializer>(init);
12087
+
12088
+ // A hack when used from getActorIsolationOfContext to maintain the
12089
+ // current behavior and avoid request cycles.
12090
+ if (ignoreDefaultArguments)
12091
+ return ActorIsolation::forUnspecified ();
12092
+
12093
+ auto fn = cast<ValueDecl>(defArgInit->getParent ()->getAsDecl ());
12094
+ auto param = getParameterAt (fn, defArgInit->getIndex ());
12095
+ assert (param);
12096
+ return param->getInitializerIsolation ();
12097
+ }
12098
+
12099
+ case InitializerKind::PropertyWrapper:
12100
+ case InitializerKind::CustomAttribute:
12101
+ return ActorIsolation::forUnspecified ();
12102
+ }
12103
+ llvm_unreachable (" bad initializer kind" );
12104
+ }
12105
+
12051
12106
bool swift::isSameActorIsolated (ValueDecl *value, DeclContext *dc) {
12052
12107
auto valueIsolation = getActorIsolation (value);
12053
12108
auto dcIsolation = getActorIsolationOfContext (dc);
0 commit comments