@@ -222,10 +222,6 @@ checkSupportedWithSectionAttribute(const Expr *expr,
222222 if (isa<KeyPathExpr>(expr))
223223 return std::make_pair (expr, KeyPath);
224224
225- // Closure expressions are not supported in constant expressions
226- if (isa<AbstractClosureExpr>(expr))
227- return std::make_pair (expr, Closure);
228-
229225 // Function conversions are allowed if the conversion is to '@convention(c)'
230226 if (auto functionConvExpr = dyn_cast<FunctionConversionExpr>(expr)) {
231227 if (auto targetFnTy =
@@ -256,6 +252,60 @@ checkSupportedWithSectionAttribute(const Expr *expr,
256252 return std::make_pair (expr, OpaqueDeclRef);
257253 }
258254
255+ // Allow specific patterns of AutoClosureExpr, which is used in static func
256+ // references. E.g. "MyStruct.staticFunc" is:
257+ // - autoclosure_expr type="() -> ()"
258+ // - call_expr type="()"
259+ // - dot_syntax_call_expr
260+ // - declref_expr decl="MyStruct.staticFunc"
261+ // - dot_self_expr type="MyStruct.Type"
262+ // - type_expr type="MyStruct.Type"
263+ if (auto autoClosureExpr = dyn_cast<AutoClosureExpr>(expr)) {
264+ auto subExpr = autoClosureExpr->getUnwrappedCurryThunkExpr ();
265+ if (auto dotSyntaxCall = dyn_cast<DotSyntaxCallExpr>(subExpr)) {
266+ if (auto declRef = dyn_cast<DeclRefExpr>(dotSyntaxCall->getFn ())) {
267+ if (auto funcDecl = dyn_cast<FuncDecl>(declRef->getDecl ())) {
268+ // Check if it's a function on a concrete non-generic type
269+ if (!funcDecl->hasGenericParamList () &&
270+ !funcDecl->getDeclContext ()->isGenericContext () &&
271+ funcDecl->isStatic ()) {
272+ if (auto args = dotSyntaxCall->getArgs ()) {
273+ if (args->size () == 1 ) {
274+ // Check that the single arg is a DotSelfExpr with only a
275+ // direct concrete TypeExpr inside
276+ if (auto dotSelfExpr =
277+ dyn_cast<DotSelfExpr>(args->get (0 ).getExpr ())) {
278+ if (const TypeExpr *typeExpr =
279+ dyn_cast<TypeExpr>(dotSelfExpr->getSubExpr ())) {
280+ auto baseType = typeExpr->getType ();
281+ if (baseType && baseType->is <MetatypeType>()) {
282+ auto instanceType =
283+ baseType->getMetatypeInstanceType ();
284+ if (auto nominal =
285+ instanceType
286+ ->getNominalOrBoundGenericNominal ()) {
287+ if (!nominal->hasGenericParamList () &&
288+ !nominal->getDeclContext ()->isGenericContext () &&
289+ !nominal->isResilient ()) {
290+ continue ;
291+ }
292+ }
293+ }
294+ }
295+ }
296+ }
297+ }
298+ }
299+ }
300+ }
301+ }
302+ return std::make_pair (expr, Default);
303+ }
304+
305+ // Other closure expressions (auto-closures) are not allowed
306+ if (isa<AbstractClosureExpr>(expr))
307+ return std::make_pair (expr, Default);
308+
259309 // DotSelfExpr for metatype references (but only a direct TypeExpr inside)
260310 if (const DotSelfExpr *dotSelfExpr = dyn_cast<DotSelfExpr>(expr)) {
261311 if (const TypeExpr *typeExpr =
0 commit comments