@@ -1098,6 +1098,21 @@ doesStorageProduceLValue(AbstractStorageDecl *storage, Type baseType,
10981098 !storage->isSetterMutating ());
10991099}
11001100
1101+ Type GetClosureType::operator ()(const AbstractClosureExpr *expr) const {
1102+ if (auto closure = dyn_cast<ClosureExpr>(expr)) {
1103+ // Look through type bindings, if we have them.
1104+ auto mutableClosure = const_cast <ClosureExpr *>(closure);
1105+ if (cs.hasType (mutableClosure)) {
1106+ return cs.getFixedTypeRecursive (
1107+ cs.getType (mutableClosure), /* wantRValue=*/ true );
1108+ }
1109+
1110+ return cs.getClosureTypeIfAvailable (closure);
1111+ }
1112+
1113+ return Type ();
1114+ }
1115+
11011116Type ConstraintSystem::getUnopenedTypeOfReference (
11021117 VarDecl *value, Type baseType, DeclContext *UseDC,
11031118 ConstraintLocator *memberLocator, bool wantInterfaceType) {
@@ -1113,18 +1128,20 @@ Type ConstraintSystem::getUnopenedTypeOfReference(
11131128
11141129 return wantInterfaceType ? var->getInterfaceType () : var->getType ();
11151130 },
1116- memberLocator, wantInterfaceType);
1131+ memberLocator, wantInterfaceType, GetClosureType{* this } );
11171132}
11181133
11191134Type ConstraintSystem::getUnopenedTypeOfReference (
11201135 VarDecl *value, Type baseType, DeclContext *UseDC,
11211136 llvm::function_ref<Type(VarDecl *)> getType,
1122- ConstraintLocator *memberLocator, bool wantInterfaceType) {
1137+ ConstraintLocator *memberLocator, bool wantInterfaceType,
1138+ llvm::function_ref<Type(const AbstractClosureExpr *)> getClosureType) {
11231139 Type requestedType =
11241140 getType (value)->getWithoutSpecifierType ()->getReferenceStorageReferent ();
11251141
11261142 // Adjust the type for concurrency.
1127- requestedType = adjustVarTypeForConcurrency (requestedType, value, UseDC);
1143+ requestedType = adjustVarTypeForConcurrency (
1144+ requestedType, value, UseDC, getClosureType);
11281145
11291146 // If we're dealing with contextual types, and we referenced this type from
11301147 // a different context, map the type.
@@ -1298,6 +1315,13 @@ static bool isRequirementOrWitness(const ConstraintLocatorBuilder &locator) {
12981315 return false ;
12991316}
13001317
1318+ AnyFunctionType *ConstraintSystem::adjustFunctionTypeForConcurrency (
1319+ AnyFunctionType *fnType, ValueDecl *decl, DeclContext *dc,
1320+ unsigned numApplies, bool isMainDispatchQueue) {
1321+ return swift::adjustFunctionTypeForConcurrency (
1322+ fnType, decl, dc, numApplies, isMainDispatchQueue, GetClosureType{*this });
1323+ }
1324+
13011325std::pair<Type, Type>
13021326ConstraintSystem::getTypeOfReference (ValueDecl *value,
13031327 FunctionRefKind functionRefKind,
@@ -1314,7 +1338,8 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
13141338 ->castTo <AnyFunctionType>();
13151339 if (!isRequirementOrWitness (locator)) {
13161340 unsigned numApplies = getNumApplications (value, false , functionRefKind);
1317- funcType = adjustFunctionTypeForConcurrency (funcType, func, useDC, numApplies, false );
1341+ funcType = adjustFunctionTypeForConcurrency (
1342+ funcType, func, useDC, numApplies, false );
13181343 }
13191344 auto openedType = openFunctionType (
13201345 funcType, locator, replacements, func->getDeclContext ());
@@ -2085,7 +2110,8 @@ Type ConstraintSystem::getEffectiveOverloadType(ConstraintLocator *locator,
20852110 } else if (type->hasDynamicSelfType ()) {
20862111 type = withDynamicSelfResultReplaced (type, /* uncurryLevel=*/ 0 );
20872112 }
2088- type = adjustVarTypeForConcurrency (type, var, useDC);
2113+ type = adjustVarTypeForConcurrency (
2114+ type, var, useDC, GetClosureType{*this });
20892115 } else if (isa<AbstractFunctionDecl>(decl) || isa<EnumElementDecl>(decl)) {
20902116 if (decl->isInstanceMember () &&
20912117 (!overload.getBaseType () ||
@@ -2339,20 +2365,18 @@ isInvalidPartialApplication(ConstraintSystem &cs,
23392365 return {true , level};
23402366}
23412367
2342- // / Walk a closure AST to determine its effects.
2343- // /
2344- // / \returns a function's extended info describing the effects, as
2345- // / determined syntactically.
23462368FunctionType::ExtInfo ConstraintSystem::closureEffects (ClosureExpr *expr) {
2347- auto known = closureEffectsCache.find (expr);
2348- if (known != closureEffectsCache.end ())
2349- return known->second ;
2369+ return evaluateOrDefault (
2370+ getASTContext ().evaluator , ClosureEffectsRequest{expr},
2371+ FunctionType::ExtInfo ());
2372+ }
23502373
2374+ FunctionType::ExtInfo ClosureEffectsRequest::evaluate (
2375+ Evaluator &evaluator, ClosureExpr *expr) const {
23512376 // A walker that looks for 'try' and 'throw' expressions
23522377 // that aren't nested within closures, nested declarations,
23532378 // or exhaustive catches.
23542379 class FindInnerThrows : public ASTWalker {
2355- ConstraintSystem &CS;
23562380 DeclContext *DC;
23572381 bool FoundThrow = false ;
23582382
@@ -2449,7 +2473,7 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
24492473 // Okay, now it should be safe to coerce the pattern.
24502474 // Pull the top-level pattern back out.
24512475 pattern = LabelItem.getPattern ();
2452- Type exnType = CS. getASTContext ().getErrorDecl ()->getDeclaredInterfaceType ();
2476+ Type exnType = DC-> getASTContext ().getErrorDecl ()->getDeclaredInterfaceType ();
24532477
24542478 if (!exnType)
24552479 return false ;
@@ -2501,8 +2525,8 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
25012525 }
25022526
25032527 public:
2504- FindInnerThrows (ConstraintSystem &cs, DeclContext *dc)
2505- : CS(cs), DC(dc) {}
2528+ FindInnerThrows (DeclContext *dc)
2529+ : DC(dc) {}
25062530
25072531 bool foundThrow () { return FoundThrow; }
25082532 };
@@ -2525,23 +2549,27 @@ FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
25252549 if (!body)
25262550 return ASTExtInfoBuilder ().withConcurrent (concurrent).build ();
25272551
2528- auto throwFinder = FindInnerThrows (* this , expr);
2552+ auto throwFinder = FindInnerThrows (expr);
25292553 body->walk (throwFinder);
2530- auto result = ASTExtInfoBuilder ()
2531- .withThrows (throwFinder.foundThrow ())
2532- .withAsync (bool (findAsyncNode (expr)))
2533- .withConcurrent (concurrent)
2534- .build ();
2535- closureEffectsCache[expr] = result;
2536- return result;
2554+ return ASTExtInfoBuilder ()
2555+ .withThrows (throwFinder.foundThrow ())
2556+ .withAsync (bool (findAsyncNode (expr)))
2557+ .withConcurrent (concurrent)
2558+ .build ();
25372559}
25382560
25392561bool ConstraintSystem::isAsynchronousContext (DeclContext *dc) {
25402562 if (auto func = dyn_cast<AbstractFunctionDecl>(dc))
25412563 return func->isAsyncContext ();
25422564
2543- if (auto closure = dyn_cast<ClosureExpr>(dc))
2544- return closureEffects (closure).isAsync ();
2565+ if (auto abstractClosure = dyn_cast<AbstractClosureExpr>(dc)) {
2566+ if (Type type = GetClosureType{*this }(abstractClosure)) {
2567+ if (auto fnType = type->getAs <AnyFunctionType>())
2568+ return fnType->isAsync ();
2569+ }
2570+
2571+ return abstractClosure->isBodyAsync ();
2572+ }
25452573
25462574 return false ;
25472575}
0 commit comments