@@ -280,6 +280,27 @@ StoredPropertiesAndMissingMembersRequest::evaluate(Evaluator &evaluator,
280280 return decl->getASTContext ().AllocateCopy (results);
281281}
282282
283+ // / Check whether the pattern may have storage.
284+ // /
285+ // / This query is careful not to trigger accessor macro expansion, which
286+ // / creates a cycle. It conservatively assumes that all accessor macros
287+ // / produce computed properties, which is... incorrect.
288+ static bool mayHaveStorage (Pattern *pattern) {
289+ // Check whether there are any accessor macros.
290+ bool hasAccessorMacros = false ;
291+ pattern->forEachVariable ([&](VarDecl *VD) {
292+ VD->forEachAttachedMacro (MacroRole::Accessor,
293+ [&](CustomAttr *customAttr, MacroDecl *macro) {
294+ hasAccessorMacros = true ;
295+ });
296+ });
297+
298+ if (hasAccessorMacros)
299+ return false ;
300+
301+ return pattern->hasStorage ();
302+ }
303+
283304// / Validate the \c entryNumber'th entry in \c binding.
284305const PatternBindingEntry *PatternBindingEntryRequest::evaluate (
285306 Evaluator &eval, PatternBindingDecl *binding, unsigned entryNumber,
@@ -380,7 +401,7 @@ const PatternBindingEntry *PatternBindingEntryRequest::evaluate(
380401 // default-initializable. If so, do it.
381402 if (!pbe.isInitialized () &&
382403 binding->isDefaultInitializable (entryNumber) &&
383- pattern-> hasStorage ( )) {
404+ mayHaveStorage (pattern )) {
384405 if (auto defaultInit = TypeChecker::buildDefaultInitializer (patternType)) {
385406 // If we got a default initializer, install it and re-type-check it
386407 // to make sure it is properly coerced to the pattern type.
0 commit comments