@@ -308,6 +308,8 @@ ExportContext::getExportabilityReason() const {
308308// / on the target platform.
309309static const AvailableAttr *getActiveAvailableAttribute (const Decl *D,
310310 ASTContext &AC) {
311+ D = abstractSyntaxDeclForAvailableAttribute (D);
312+
311313 for (auto Attr : D->getAttrs ())
312314 if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) {
313315 if (!AvAttr->isInvalid () && AvAttr->isActivePlatform (AC)) {
@@ -494,7 +496,10 @@ class TypeRefinementContextBuilder : private ASTWalker {
494496 // / Returns a new context to be introduced for the declaration, or nullptr
495497 // / if no new context should be introduced.
496498 TypeRefinementContext *getNewContextForSignatureOfDecl (Decl *D) {
497- if (!isa<ValueDecl>(D) && !isa<ExtensionDecl>(D) && !isa<MacroExpansionDecl>(D))
499+ if (!isa<ValueDecl>(D) &&
500+ !isa<ExtensionDecl>(D) &&
501+ !isa<MacroExpansionDecl>(D) &&
502+ !isa<PatternBindingDecl>(D))
498503 return nullptr ;
499504
500505 // Only introduce for an AbstractStorageDecl if it is not local. We
@@ -503,20 +508,17 @@ class TypeRefinementContextBuilder : private ASTWalker {
503508 if (isa<AbstractStorageDecl>(D) && D->getDeclContext ()->isLocalContext ())
504509 return nullptr ;
505510
511+ // Don't introduce for variable declarations that have a parent pattern
512+ // binding; all of the relevant information is on the pattern binding.
513+ if (auto var = dyn_cast<VarDecl>(D)) {
514+ if (var->getParentPatternBinding ())
515+ return nullptr ;
516+ }
517+
506518 // Ignore implicit declarations (mainly skips over `DeferStmt` functions).
507519 if (D->isImplicit ())
508520 return nullptr ;
509521
510- // Skip introducing additional contexts for var decls past the first in a
511- // pattern. The context necessary for the pattern as a whole was already
512- // introduced if necessary by the first var decl.
513- if (auto *VD = dyn_cast<VarDecl>(D)) {
514- if (auto *PBD = VD->getParentPatternBinding ()) {
515- if (VD != PBD->getAnchoringVarDecl (0 ))
516- return nullptr ;
517- }
518- }
519-
520522 // Declarations with an explicit availability attribute always get a TRC.
521523 if (hasActiveAvailableAttribute (D, Context)) {
522524 AvailabilityContext DeclaredAvailability =
@@ -541,7 +543,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
541543 getCurrentTRC ()->getAvailabilityInfo ();
542544 AvailabilityContext EffectiveAvailability =
543545 getEffectiveAvailabilityForDeclSignature (D, CurrentAvailability);
544- if ((isa<VarDecl>(D) && refinementSourceRangeForDecl (D).isValid ()) ||
546+ if ((isa<PatternBindingDecl>(D) &&
547+ refinementSourceRangeForDecl (D).isValid ()) ||
545548 CurrentAvailability.isSupersetOf (EffectiveAvailability))
546549 return TypeRefinementContext::createForDeclImplicit (
547550 Context, D, getCurrentTRC (), EffectiveAvailability,
@@ -617,22 +620,6 @@ class TypeRefinementContextBuilder : private ASTWalker {
617620 // the bodies of its accessors.
618621 SourceRange Range = storageDecl->getSourceRange ();
619622
620- // For a variable declaration (without accessors) we use the range of the
621- // containing pattern binding declaration to make sure that we include
622- // any type annotation in the type refinement context range. We also
623- // need to include any custom attributes that were written on the
624- // declaration.
625- if (auto *varDecl = dyn_cast<VarDecl>(storageDecl)) {
626- if (auto *PBD = varDecl->getParentPatternBinding ())
627- Range = PBD->getSourceRange ();
628-
629- for (auto attr : varDecl->getOriginalAttrs ()) {
630- if (auto customAttr = dyn_cast<CustomAttr>(attr)) {
631- Range.widen (customAttr->getRange ());
632- }
633- }
634- }
635-
636623 // HACK: For synthesized trivial accessors we may have not a valid
637624 // location for the end of the braces, so in that case we will fall back
638625 // to using the range for the storage declaration. The right fix here is
@@ -646,7 +633,13 @@ class TypeRefinementContextBuilder : private ASTWalker {
646633
647634 return Range;
648635 }
649-
636+
637+ // For pattern binding declarations, include the attributes in the source
638+ // range so that we're sure to cover any property wrappers.
639+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(D)) {
640+ return D->getSourceRangeIncludingAttrs ();
641+ }
642+
650643 return D->getSourceRange ();
651644 }
652645
@@ -662,7 +655,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
662655 Context, D, getCurrentTRC (), Availability, range);
663656 }
664657
665- // / Build contexts for a VarDecl with the given initializer .
658+ // / Build contexts for a pattern binding declaration .
666659 void buildContextsForPatternBindingDecl (PatternBindingDecl *pattern) {
667660 // Build contexts for each of the pattern entries.
668661 for (unsigned index : range (pattern->getNumPatternEntries ())) {
@@ -1241,22 +1234,11 @@ bool ExpandChildTypeRefinementContextsRequest::evaluate(
12411234 if (computeContainedByDeploymentTarget (parentTRC, ctx))
12421235 return false ;
12431236
1244- // Variables can have children corresponding to property wrappers and
1245- // the initial values provided in each pattern binding entry.
1246- if (auto var = dyn_cast<VarDecl>(decl)) {
1247- if (auto *pattern = var->getParentPatternBinding ()) {
1248- // Only do this for the first variable in the pattern binding declaration.
1249- auto anchorVar = pattern->getAnchoringVarDecl (0 );
1250- if (anchorVar != var) {
1251- return evaluateOrDefault (
1252- evaluator,
1253- ExpandChildTypeRefinementContextsRequest{anchorVar, parentTRC},
1254- false );
1255- }
1256-
1257- TypeRefinementContextBuilder builder (parentTRC, ctx);
1258- builder.buildContextsForPatternBindingDecl (pattern);
1259- }
1237+ // Pattern binding declarations can have children corresponding to property
1238+ // wrappers and the initial values provided in each pattern binding entry.
1239+ if (auto *binding = dyn_cast<PatternBindingDecl>(decl)) {
1240+ TypeRefinementContextBuilder builder (parentTRC, ctx);
1241+ builder.buildContextsForPatternBindingDecl (binding);
12601242 }
12611243
12621244 return false ;
@@ -1596,38 +1578,6 @@ concreteSyntaxDeclForAvailableAttribute(const Decl *AbstractSyntaxDecl) {
15961578 return AbstractSyntaxDecl;
15971579}
15981580
1599- // / Given a declaration upon which an availability attribute would appear in
1600- // / concrete syntax, return a declaration to which the parser
1601- // / actually attaches the attribute in the abstract syntax tree. We use this
1602- // / function to determine whether the concrete syntax already has an
1603- // / availability attribute.
1604- static const Decl *
1605- abstractSyntaxDeclForAvailableAttribute (const Decl *ConcreteSyntaxDecl) {
1606- // This function needs to be kept in sync with its counterpart,
1607- // concreteSyntaxDeclForAvailableAttribute().
1608-
1609- if (auto *PBD = dyn_cast<PatternBindingDecl>(ConcreteSyntaxDecl)) {
1610- // Existing @available attributes in the AST are attached to VarDecls
1611- // rather than PatternBindingDecls, so we return the first VarDecl for
1612- // the pattern binding declaration.
1613- // This is safe, even though there may be multiple VarDecls, because
1614- // all parsed attribute that appear in the concrete syntax upon on the
1615- // PatternBindingDecl are added to all of the VarDecls for the pattern
1616- // binding.
1617- if (PBD->getNumPatternEntries () != 0 ) {
1618- return PBD->getAnchoringVarDecl (0 );
1619- }
1620- } else if (auto *ECD = dyn_cast<EnumCaseDecl>(ConcreteSyntaxDecl)) {
1621- // Similar to the PatternBindingDecl case above, we return the
1622- // first EnumElementDecl.
1623- if (auto *Elem = ECD->getFirstElement ()) {
1624- return Elem;
1625- }
1626- }
1627-
1628- return ConcreteSyntaxDecl;
1629- }
1630-
16311581// / Given a declaration, return a better related declaration for which
16321582// / to suggest an @available fixit, or the original declaration
16331583// / if no such related declaration exists.
0 commit comments