@@ -308,6 +308,8 @@ ExportContext::getExportabilityReason() const {
308
308
// / on the target platform.
309
309
static const AvailableAttr *getActiveAvailableAttribute (const Decl *D,
310
310
ASTContext &AC) {
311
+ D = abstractSyntaxDeclForAvailableAttribute (D);
312
+
311
313
for (auto Attr : D->getAttrs ())
312
314
if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) {
313
315
if (!AvAttr->isInvalid () && AvAttr->isActivePlatform (AC)) {
@@ -494,7 +496,10 @@ class TypeRefinementContextBuilder : private ASTWalker {
494
496
// / Returns a new context to be introduced for the declaration, or nullptr
495
497
// / if no new context should be introduced.
496
498
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))
498
503
return nullptr ;
499
504
500
505
// Only introduce for an AbstractStorageDecl if it is not local. We
@@ -503,20 +508,17 @@ class TypeRefinementContextBuilder : private ASTWalker {
503
508
if (isa<AbstractStorageDecl>(D) && D->getDeclContext ()->isLocalContext ())
504
509
return nullptr ;
505
510
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
+
506
518
// Ignore implicit declarations (mainly skips over `DeferStmt` functions).
507
519
if (D->isImplicit ())
508
520
return nullptr ;
509
521
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
-
520
522
// Declarations with an explicit availability attribute always get a TRC.
521
523
if (hasActiveAvailableAttribute (D, Context)) {
522
524
AvailabilityContext DeclaredAvailability =
@@ -541,7 +543,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
541
543
getCurrentTRC ()->getAvailabilityInfo ();
542
544
AvailabilityContext EffectiveAvailability =
543
545
getEffectiveAvailabilityForDeclSignature (D, CurrentAvailability);
544
- if ((isa<VarDecl>(D) && refinementSourceRangeForDecl (D).isValid ()) ||
546
+ if ((isa<PatternBindingDecl>(D) &&
547
+ refinementSourceRangeForDecl (D).isValid ()) ||
545
548
CurrentAvailability.isSupersetOf (EffectiveAvailability))
546
549
return TypeRefinementContext::createForDeclImplicit (
547
550
Context, D, getCurrentTRC (), EffectiveAvailability,
@@ -617,22 +620,6 @@ class TypeRefinementContextBuilder : private ASTWalker {
617
620
// the bodies of its accessors.
618
621
SourceRange Range = storageDecl->getSourceRange ();
619
622
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
-
636
623
// HACK: For synthesized trivial accessors we may have not a valid
637
624
// location for the end of the braces, so in that case we will fall back
638
625
// to using the range for the storage declaration. The right fix here is
@@ -646,7 +633,13 @@ class TypeRefinementContextBuilder : private ASTWalker {
646
633
647
634
return Range;
648
635
}
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
+
650
643
return D->getSourceRange ();
651
644
}
652
645
@@ -662,7 +655,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
662
655
Context, D, getCurrentTRC (), Availability, range);
663
656
}
664
657
665
- // / Build contexts for a VarDecl with the given initializer .
658
+ // / Build contexts for a pattern binding declaration .
666
659
void buildContextsForPatternBindingDecl (PatternBindingDecl *pattern) {
667
660
// Build contexts for each of the pattern entries.
668
661
for (unsigned index : range (pattern->getNumPatternEntries ())) {
@@ -1241,22 +1234,11 @@ bool ExpandChildTypeRefinementContextsRequest::evaluate(
1241
1234
if (computeContainedByDeploymentTarget (parentTRC, ctx))
1242
1235
return false ;
1243
1236
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);
1260
1242
}
1261
1243
1262
1244
return false ;
@@ -1596,38 +1578,6 @@ concreteSyntaxDeclForAvailableAttribute(const Decl *AbstractSyntaxDecl) {
1596
1578
return AbstractSyntaxDecl;
1597
1579
}
1598
1580
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
-
1631
1581
// / Given a declaration, return a better related declaration for which
1632
1582
// / to suggest an @available fixit, or the original declaration
1633
1583
// / if no such related declaration exists.
0 commit comments