@@ -1453,20 +1453,26 @@ ConstraintSystem::getTypeOfMemberReference(
1453
1453
const DeclRefExpr *base,
1454
1454
OpenedTypeMap *replacementsPtr) {
1455
1455
// Figure out the instance type used for the base.
1456
- Type baseObjTy = getFixedTypeRecursive (baseTy, /* wantRValue=*/ true );
1456
+ Type resolvedBaseTy = getFixedTypeRecursive (baseTy, /* wantRValue=*/ true );
1457
1457
1458
1458
// If the base is a module type, just use the type of the decl.
1459
- if (baseObjTy ->is <ModuleType>()) {
1459
+ if (resolvedBaseTy ->is <ModuleType>()) {
1460
1460
return getTypeOfReference (value, functionRefKind, locator, useDC);
1461
1461
}
1462
1462
1463
1463
// Check to see if the self parameter is applied, in which case we'll want to
1464
1464
// strip it off later.
1465
- auto hasAppliedSelf = doesMemberRefApplyCurriedSelf (baseObjTy , value);
1465
+ auto hasAppliedSelf = doesMemberRefApplyCurriedSelf (resolvedBaseTy , value);
1466
1466
1467
- baseObjTy = baseObjTy ->getMetatypeInstanceType ();
1467
+ auto baseObjTy = resolvedBaseTy ->getMetatypeInstanceType ();
1468
1468
FunctionType::Param baseObjParam (baseObjTy);
1469
1469
1470
+ // Indicates whether this is a reference to a static member on a protocol
1471
+ // metatype e.g. existential metatype.
1472
+ bool isStaticMemberRefOnProtocol = resolvedBaseTy->is <MetatypeType>() &&
1473
+ baseObjTy->isExistentialType () &&
1474
+ value->isStatic ();
1475
+
1470
1476
if (auto *typeDecl = dyn_cast<TypeDecl>(value)) {
1471
1477
assert (!isa<ModuleDecl>(typeDecl) && " Nested module?" );
1472
1478
@@ -1569,10 +1575,28 @@ ConstraintSystem::getTypeOfMemberReference(
1569
1575
1570
1576
// If we are looking at a member of an existential, open the existential.
1571
1577
Type baseOpenedTy = baseObjTy;
1572
- if (baseObjTy->isExistentialType ()) {
1578
+
1579
+ if (isStaticMemberRefOnProtocol) {
1580
+ auto refTy = openedType->castTo <FunctionType>();
1581
+ switch (functionRefKind) {
1582
+ // Either variable or use of method as a value
1583
+ case FunctionRefKind::Unapplied:
1584
+ case FunctionRefKind::SingleApply:
1585
+ case FunctionRefKind::Compound: {
1586
+ baseOpenedTy =
1587
+ isa<AbstractFunctionDecl>(value)
1588
+ ? refTy->getResult ()->castTo <FunctionType>()->getResult ()
1589
+ : refTy->getResult ();
1590
+ break ;
1591
+ }
1592
+
1593
+ case FunctionRefKind::DoubleApply:
1594
+ llvm_unreachable (" not implemented yet" );
1595
+ }
1596
+ } else if (baseObjTy->isExistentialType ()) {
1573
1597
auto openedArchetype = OpenedArchetypeType::get (baseObjTy);
1574
- OpenedExistentialTypes.push_back ({ getConstraintLocator (locator),
1575
- openedArchetype });
1598
+ OpenedExistentialTypes.push_back (
1599
+ { getConstraintLocator (locator), openedArchetype});
1576
1600
baseOpenedTy = openedArchetype;
1577
1601
}
1578
1602
@@ -1582,11 +1606,18 @@ ConstraintSystem::getTypeOfMemberReference(
1582
1606
1583
1607
Type selfObjTy = openedParams.front ().getPlainType ()->getMetatypeInstanceType ();
1584
1608
if (outerDC->getSelfProtocolDecl ()) {
1585
- // For a protocol, substitute the base object directly. We don't need a
1586
- // conformance constraint because we wouldn't have found the declaration
1587
- // if it didn't conform.
1588
- addConstraint (ConstraintKind::Bind, baseOpenedTy, selfObjTy,
1589
- getConstraintLocator (locator));
1609
+ if (isStaticMemberRefOnProtocol) {
1610
+ // If this is a static member reference on a protocol metatype
1611
+ // we need to make sure that base type, we yet to infer from a
1612
+ // result type of the member, does indeed conform to `Self`.
1613
+ addSelfConstraint (*this , baseOpenedTy, selfObjTy, locator);
1614
+ } else {
1615
+ // For a protocol, substitute the base object directly. We don't need a
1616
+ // conformance constraint because we wouldn't have found the declaration
1617
+ // if it didn't conform.
1618
+ addConstraint (ConstraintKind::Bind, baseOpenedTy, selfObjTy,
1619
+ getConstraintLocator (locator));
1620
+ }
1590
1621
} else if (!isDynamicResult) {
1591
1622
addSelfConstraint (*this , baseOpenedTy, selfObjTy, locator);
1592
1623
}
0 commit comments