@@ -1640,27 +1640,62 @@ bool isMutatingMethod(const ValueDecl *decl) {
1640
1640
return cast<FuncDecl>(decl)->isMutating ();
1641
1641
}
1642
1642
1643
+ static bool shouldCheckForPartialApplication (ConstraintSystem &cs,
1644
+ const ValueDecl *decl,
1645
+ ConstraintLocator *locator) {
1646
+ auto *anchor = locator->getAnchor ();
1647
+ if (!(anchor && isa<UnresolvedDotExpr>(anchor)))
1648
+ return false ;
1649
+
1650
+ // FIXME(diagnostics): This check should be removed together with
1651
+ // expression based diagnostics.
1652
+ if (cs.TC .isExprBeingDiagnosed (anchor))
1653
+ return false ;
1654
+
1655
+ // If this is a reference to instance method marked as 'mutating'
1656
+ // it should be checked for invalid partial application.
1657
+ if (isMutatingMethod (decl))
1658
+ return true ;
1659
+
1660
+ // Another unsupported partial application is related
1661
+ // to constructor delegation via `self.init` or `super.init`.
1662
+
1663
+ if (!isa<ConstructorDecl>(decl))
1664
+ return false ;
1665
+
1666
+ auto *UDE = cast<UnresolvedDotExpr>(anchor);
1667
+ // This is `super.init`
1668
+ if (UDE->getBase ()->isSuperExpr ())
1669
+ return true ;
1670
+
1671
+ // Or this might be `self.init`.
1672
+ if (auto *DRE = dyn_cast<DeclRefExpr>(UDE->getBase ())) {
1673
+ if (auto *baseDecl = DRE->getDecl ())
1674
+ return baseDecl->getBaseName () == cs.getASTContext ().Id_self ;
1675
+ }
1676
+
1677
+ return false ;
1678
+ }
1679
+
1643
1680
// / Try to identify and fix failures related to partial function application
1644
1681
// / e.g. partial application of `init` or 'mutating' instance methods.
1645
1682
static std::pair<bool , unsigned >
1646
1683
isInvalidPartialApplication (ConstraintSystem &cs, const ValueDecl *member,
1647
1684
ConstraintLocator *locator) {
1648
- if (!isMutatingMethod (member))
1649
- return {false , 0 };
1650
-
1651
- auto *anchor = locator->getAnchor ();
1652
- if (!isa<UnresolvedDotExpr>(anchor))
1685
+ if (!shouldCheckForPartialApplication (cs, member, locator))
1653
1686
return {false , 0 };
1654
1687
1688
+ auto anchor = cast<UnresolvedDotExpr>(locator->getAnchor ());
1655
1689
// If this choice is a partial application of `init` or
1656
1690
// `mutating` instance method we should report that it's not allowed.
1657
- auto baseTy = cs.getType (cast<UnresolvedDotExpr>(anchor)->getBase ())
1658
- ->getWithoutSpecifierType ();
1659
-
1660
- // If base is a metatype it would be ignored, but if it is
1661
- // some other type it means that we have a single application
1662
- // level already.
1663
- unsigned level = cs.simplifyType (baseTy)->is <MetatypeType>() ? 0 : 1 ;
1691
+ auto baseTy =
1692
+ cs.simplifyType (cs.getType (anchor->getBase ()))->getWithoutSpecifierType ();
1693
+
1694
+ // If base is a metatype it would be ignored (unless this is an initializer
1695
+ // call), but if it is some other type it means that we have a single
1696
+ // application level already.
1697
+ unsigned level =
1698
+ baseTy->is <MetatypeType>() && !isa<ConstructorDecl>(member) ? 0 : 1 ;
1664
1699
if (auto *call = dyn_cast_or_null<CallExpr>(cs.getParentExpr (anchor))) {
1665
1700
level += dyn_cast_or_null<CallExpr>(cs.getParentExpr (call)) ? 2 : 1 ;
1666
1701
}
@@ -1926,6 +1961,11 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
1926
1961
// partial function application e.g. partial application of
1927
1962
// mutating method or initializer.
1928
1963
1964
+ // This check is supposed to be performed without
1965
+ // `shouldAttemptFixes` because name lookup can't
1966
+ // detect that particular partial application is
1967
+ // invalid, so it has to return all of the candidates.
1968
+
1929
1969
bool isInvalidPartialApply;
1930
1970
unsigned level;
1931
1971
0 commit comments