@@ -1565,30 +1565,6 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1565
1565
1566
1566
if (!DRE || !DRE->isImplicit ())
1567
1567
return false ;
1568
-
1569
- // Defensive check for type. If the expression doesn't have type here, it
1570
- // should have been diagnosed somewhere else.
1571
- Type ty = DRE->getType ();
1572
- assert (ty && " Implicit self parameter ref without type" );
1573
- if (!ty)
1574
- return false ;
1575
-
1576
- // Metatype self captures don't extend the lifetime of an object.
1577
- if (ty->is <MetatypeType>())
1578
- return false ;
1579
-
1580
- // If self does not have reference semantics, it is very unlikely that
1581
- // capturing it will create a reference cycle.
1582
- if (!ty->hasReferenceSemantics ())
1583
- return false ;
1584
-
1585
- // If this is an implicit self parameter to a `AbstractFunctionDecl`
1586
- // (`FuncDecl`, `ConstructorDecl`, or `DestructorDecl`,
1587
- // `@autoclosure @escaping () -> String = String()` as one example)
1588
- // then it isn't actually capturing the closure's 'self', and is fine.
1589
- if (isa<AbstractFunctionDecl>(DRE->getDecl ())) {
1590
- return false ;
1591
- }
1592
1568
1593
1569
// If this decl isn't named "self", then it isn't an implicit self capture
1594
1570
// and we have no reason to reject it.
@@ -1600,73 +1576,82 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1600
1576
auto isExplicitWeakSelfCapture = false ;
1601
1577
if (auto closureExpr = dyn_cast<ClosureExpr>(inClosure)) {
1602
1578
if (auto selfDecl = closureExpr->getCapturedSelfDecl ()) {
1603
- // If `weak self` was captured explicitly, then implicit self
1604
- // is always allowed allowed once `self` is unwrapped.
1605
- // - If `self` is still an Optional, compilation would have failed already,
1606
- // so we don't need to check for that here.
1607
1579
if (selfDecl->getType ()->is <WeakStorageType>()) {
1608
1580
isExplicitWeakSelfCapture = true ;
1609
1581
}
1610
-
1611
- // If this capture is using the name `self` actually referring
1612
- // to some other variable (e.g. with `[self = "hello"]`)
1613
- // then implicit self is not allowed.
1614
- else if (!selfDecl->isSelfParamCapture ()) {
1615
- return true ;
1616
- }
1617
1582
}
1618
1583
}
1619
1584
1620
- if (auto var = dyn_cast<VarDecl>(DRE->getDecl ())) {
1621
- if (auto parentStmt = var->getParentPatternStmt ()) {
1622
- if (isa<LabeledConditionalStmt>(parentStmt)) {
1623
- // If this `self` decl was not captured explicitly by this closure,
1624
- // but is actually from an outer `weak` capture's `if let self = self`
1625
- // or `guard let self = self` etc, then we don't allow implicit self.
1626
- if (!isExplicitWeakSelfCapture) {
1627
- return true ;
1628
- }
1629
-
1630
- // If this is an explicit `weak self` capture, then we need
1631
- // to validate that the unwrapped `self` decl is actually
1632
- // referring to `self`, and not something else like in
1633
- // `guard let self = .someOptionalVariable else { return }`
1634
- auto hasCorrectSelfBindingCondition = false ;
1635
- for (auto cond : dyn_cast<LabeledConditionalStmt>(parentStmt)->getCond ()) {
1636
- if (cond.getKind () == StmtConditionElement::CK_PatternBinding) {
1637
- if (auto optionalPattern = dyn_cast<OptionalSomePattern>(cond.getPattern ())) {
1585
+ // If this is an explicit `weak self` capture, then implicit self is allowed
1586
+ // once the closure's self param is unwrapped. We need to validate that the
1587
+ // unwrapped `self` decl specifically refers to an unwrapped copy of the
1588
+ // closure's `self` param, and not something else like in
1589
+ // `guard let self = .someOptionalVariable else { return }` or
1590
+ // `let self = someUnrelatedVariable`. If self hasn't been unwrapped yet
1591
+ // and is still an optional, we would have already hit an error elsewhere.
1592
+ if (isExplicitWeakSelfCapture) {
1593
+ bool hasCorrectSelfBindingCondition = false ;
1594
+ if (auto var = dyn_cast<VarDecl>(DRE->getDecl ())) {
1595
+ // if the `self` decls was defined in a `let`, `guard`, or `while` condition...
1596
+ if (auto parentStmt = var->getParentPatternStmt ())
1597
+ if (auto parentConditionalStmt = dyn_cast<LabeledConditionalStmt>(parentStmt))
1598
+ for (auto cond : parentConditionalStmt->getCond ())
1599
+ if (auto optionalPattern = dyn_cast_or_null<OptionalSomePattern>(cond.getPattern ()))
1638
1600
// if the lhs of the optional binding is `self`...
1639
- if (optionalPattern->getSubPattern ()->getBoundName () == Ctx.Id_self ) {
1640
- if (auto loadExpr = dyn_cast<LoadExpr>(cond.getInitializer ())) {
1641
- if (auto declRefExpr = dyn_cast<DeclRefExpr>(loadExpr->getSubExpr ())) {
1601
+ if (optionalPattern->getSubPattern ()->getBoundName () == Ctx.Id_self )
1602
+ if (auto loadExpr = dyn_cast<LoadExpr>(cond.getInitializer ()))
1603
+ if (auto declRefExpr = dyn_cast<DeclRefExpr>(loadExpr->getSubExpr ()))
1642
1604
// and the rhs of the optional binding is `self`...
1643
- if (declRefExpr->getDecl ()->getName ().isSimpleName (Ctx.Id_self )) {
1644
- // then we can permit implicit self in this closure
1605
+ if (declRefExpr->getDecl ()->getName ().isSimpleName (Ctx.Id_self ))
1606
+ // then we can permit implicit self in this case
1645
1607
hasCorrectSelfBindingCondition = true ;
1646
- }
1647
- }
1648
- }
1649
- }
1650
- }
1651
- }
1652
- }
1653
-
1654
- return !hasCorrectSelfBindingCondition;
1655
- }
1656
1608
}
1657
1609
1658
- if (!isEnclosingSelfReference (var, inClosure)) {
1659
- return false ;
1660
- }
1610
+ return !hasCorrectSelfBindingCondition;
1661
1611
}
1662
1612
1613
+ // Defensive check for type. If the expression doesn't have type here, it
1614
+ // should have been diagnosed somewhere else.
1615
+ Type ty = DRE->getType ();
1616
+ assert (ty && " Implicit self parameter ref without type" );
1617
+ if (!ty)
1618
+ return false ;
1619
+
1620
+ // Metatype self captures don't extend the lifetime of an object.
1621
+ if (ty->is <MetatypeType>())
1622
+ return false ;
1623
+
1624
+ // If self does not have reference semantics, it is very unlikely that
1625
+ // capturing it will create a reference cycle.
1626
+ if (!ty->hasReferenceSemantics ())
1627
+ return false ;
1628
+
1629
+ if (auto closureExpr = dyn_cast<ClosureExpr>(inClosure))
1630
+ if (auto selfDecl = closureExpr->getCapturedSelfDecl ())
1631
+ // If this capture is using the name `self` actually referring
1632
+ // to some other variable (e.g. with `[self = "hello"]`)
1633
+ // then implicit self is not allowed.
1634
+ if (!selfDecl->isSelfParamCapture ())
1635
+ return true ;
1636
+
1637
+ if (auto var = dyn_cast<VarDecl>(DRE->getDecl ()))
1638
+ if (!isEnclosingSelfReference (var, inClosure))
1639
+ return false ;
1640
+
1663
1641
return true ;
1664
1642
}
1665
1643
1666
1644
// / Return true if this is a closure expression that will require explicit
1667
1645
// / use or capture of "self." for qualification of member references.
1668
1646
static bool isClosureRequiringSelfQualification (
1669
1647
const AbstractClosureExpr *CE) {
1648
+ // If this closure capture self weakly, then we have to validate each usage
1649
+ // of implicit self individually, even in a nonescaping closure
1650
+ if (auto closureExpr = dyn_cast<ClosureExpr>(CE))
1651
+ if (auto selfDecl = closureExpr->getCapturedSelfDecl ())
1652
+ if (selfDecl->getType ()->is <WeakStorageType>())
1653
+ return true ;
1654
+
1670
1655
// If the closure's type was inferred to be noescape, then it doesn't
1671
1656
// need qualification.
1672
1657
if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(CE))
@@ -1713,23 +1698,19 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1713
1698
// Until Swift 6, only emit a warning when we get this with an
1714
1699
// explicit capture, since we used to not diagnose this at all.
1715
1700
auto shouldOnlyWarn = [&](Expr *selfRef) {
1716
- if (auto declRef = dyn_cast<DeclRefExpr>(selfRef)) {
1717
- if (auto decl = declRef->getDecl ()) {
1718
- if (auto varDecl = dyn_cast<VarDecl>(decl)) {
1719
- // If the self decl was defined in an conditional binding in an `if`/`guard`/`while`,
1720
- // then we know this is an inner closure of some outer closure's `weak self` capture.
1721
- // Since this wasn't allowed in Swift 5.5, we should just always emit an error.
1722
- if (auto parentStmt = varDecl->getParentPatternStmt ()) {
1723
- if (isa<LabeledConditionalStmt>(parentStmt)) {
1724
- return false ;
1725
- }
1726
- }
1727
-
1701
+ // If this implicit self decl is from a closure that captured self weakly,
1702
+ // then we should always emit an error, since implicit self was only
1703
+ // allowed starting in Swift 5.8 and later.
1704
+ if (auto closureExpr = dyn_cast<ClosureExpr>(ACE))
1705
+ if (auto selfDecl = closureExpr->getCapturedSelfDecl ())
1706
+ if (selfDecl->getType ()->is <WeakStorageType>())
1707
+ return false ;
1708
+
1709
+ if (auto declRef = dyn_cast<DeclRefExpr>(selfRef))
1710
+ if (auto decl = declRef->getDecl ())
1711
+ if (auto varDecl = dyn_cast<VarDecl>(decl))
1728
1712
return !varDecl->isSelfParameter ();
1729
- }
1730
- }
1731
- }
1732
-
1713
+
1733
1714
return false ;
1734
1715
};
1735
1716
0 commit comments