@@ -1427,6 +1427,111 @@ void ConstraintSystem::openGenericRequirement(
1427
1427
preparedOverload);
1428
1428
}
1429
1429
1430
+ DeclReferenceType ConstraintSystem::getTypeOfMemberTypeReference (
1431
+ Type baseObjTy, TypeDecl *typeDecl, ConstraintLocator *locator,
1432
+ PreparedOverloadBuilder *preparedOverload) {
1433
+ assert (!isa<ModuleDecl>(typeDecl) && " Nested module?" );
1434
+
1435
+ auto memberTy = TypeChecker::substMemberTypeWithBase (typeDecl, baseObjTy);
1436
+
1437
+ // If the member type is a constraint, e.g. because the
1438
+ // reference is to a typealias with an underlying protocol
1439
+ // or composition type, the member reference has existential
1440
+ // type.
1441
+ if (memberTy->isConstraintType ())
1442
+ memberTy = ExistentialType::get (memberTy);
1443
+
1444
+ checkNestedTypeConstraints (*this , memberTy, locator, preparedOverload);
1445
+
1446
+ // Convert any placeholders and open any generics.
1447
+ memberTy = replaceInferableTypesWithTypeVars (
1448
+ memberTy, locator, preparedOverload);
1449
+
1450
+ // Wrap it in a metatype, unless this is a value generic.
1451
+ // 'substMemberTypeWithBase' returns the underlying value type
1452
+ // of the value generic (e.g. 'Int').
1453
+ if (!isa<GenericTypeParamDecl>(typeDecl) ||
1454
+ !cast<GenericTypeParamDecl>(typeDecl)->isValue ()) {
1455
+ memberTy = MetatypeType::get (memberTy);
1456
+ }
1457
+
1458
+ FunctionType::Param baseObjParam (baseObjTy);
1459
+ auto openedType = FunctionType::get ({baseObjParam}, memberTy);
1460
+ return { openedType, openedType, memberTy, memberTy, Type () };
1461
+ }
1462
+
1463
+ std::pair<Type, Type> ConstraintSystem::getOpenedStorageType (
1464
+ Type baseTy, AbstractStorageDecl *value, DeclContext *useDC,
1465
+ bool hasAppliedSelf, ArrayRef<OpenedType> replacements,
1466
+ ConstraintLocator *locator, PreparedOverloadBuilder *preparedOverload) {
1467
+ Type thrownErrorType;
1468
+
1469
+ if (auto accessor = value->getEffectfulGetAccessor ()) {
1470
+ thrownErrorType = accessor->getEffectiveThrownErrorType ().value_or (Type ());
1471
+ }
1472
+
1473
+ // For a property, build a type (Self) -> PropType.
1474
+ // For a subscript, build a type (Self) -> (Indices...) throws(?) -> ElementType.
1475
+ //
1476
+ // If the access is mutating, wrap the storage type in an lvalue type.
1477
+ Type refType;
1478
+ if (auto *subscript = dyn_cast<SubscriptDecl>(value)) {
1479
+ auto elementTy = subscript->getElementInterfaceType ();
1480
+
1481
+ if (doesStorageProduceLValue (subscript, baseTy, useDC, *this , locator))
1482
+ elementTy = LValueType::get (elementTy);
1483
+
1484
+ auto indices = subscript->getInterfaceType ()
1485
+ ->castTo <AnyFunctionType>()->getParams ();
1486
+
1487
+ // Transfer the thrown error type into the subscript reference type,
1488
+ // which will be used in the application.
1489
+ FunctionType::ExtInfo info;
1490
+ if (thrownErrorType) {
1491
+ info = info.withThrows (true , thrownErrorType);
1492
+ thrownErrorType = Type ();
1493
+ }
1494
+
1495
+ refType = FunctionType::get (indices, elementTy, info);
1496
+ } else {
1497
+ // Delay the adjustment for preconcurrency until after we've formed
1498
+ // the function type for this kind of reference. Otherwise we will lose
1499
+ // track of the adjustment in the formed function's return type.
1500
+
1501
+ refType = getUnopenedTypeOfReference (cast<VarDecl>(value), baseTy, useDC,
1502
+ locator,
1503
+ /* wantInterfaceType=*/ true );
1504
+ }
1505
+
1506
+ auto *outerDC = value->getDeclContext ();
1507
+ auto selfTy = outerDC->getSelfInterfaceType ();
1508
+
1509
+ // If this is a reference to an instance member that applies self,
1510
+ // where self is a value type and the base type is an lvalue, wrap it in an
1511
+ // inout type.
1512
+ auto selfFlags = ParameterTypeFlags ();
1513
+ if (value->isInstanceMember () && hasAppliedSelf &&
1514
+ !outerDC->getDeclaredInterfaceType ()->hasReferenceSemantics () &&
1515
+ baseTy->is <LValueType>() &&
1516
+ !selfTy->hasError ())
1517
+ selfFlags = selfFlags.withInOut (true );
1518
+
1519
+ // If the storage is generic, open the self and ref types.
1520
+ selfTy = openType (selfTy, replacements, locator, preparedOverload);
1521
+ refType = openType (refType, replacements, locator, preparedOverload);
1522
+
1523
+ if (thrownErrorType) {
1524
+ thrownErrorType = openType (thrownErrorType, replacements, locator,
1525
+ preparedOverload);
1526
+ }
1527
+
1528
+ FunctionType::Param selfParam (selfTy, Identifier (), selfFlags);
1529
+
1530
+ FunctionType::ExtInfo info;
1531
+ return std::make_pair (thrownErrorType,
1532
+ FunctionType::get ({selfParam}, refType, info));
1533
+ }
1534
+
1430
1535
// / Add the constraint on the type used for the 'Self' type for a member
1431
1536
// / reference.
1432
1537
// /
@@ -1552,9 +1657,11 @@ static bool isExistentialMemberAccessWithExplicitBaseExpression(
1552
1657
}
1553
1658
1554
1659
Type ConstraintSystem::getMemberReferenceTypeFromOpenedType (
1555
- Type type, Type baseObjTy, ValueDecl *value, DeclContext *outerDC,
1660
+ Type type, Type baseObjTy, ValueDecl *value,
1556
1661
ConstraintLocator *locator, bool hasAppliedSelf, bool isDynamicLookup,
1557
1662
ArrayRef<OpenedType> replacements) {
1663
+ auto *outerDC = value->getDeclContext ();
1664
+
1558
1665
// Cope with dynamic 'Self'.
1559
1666
if (outerDC->getSelfClassDecl ()) {
1560
1667
if (type->hasDynamicSelfType ()) {
@@ -1667,34 +1774,8 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1667
1774
}
1668
1775
1669
1776
if (auto *typeDecl = dyn_cast<TypeDecl>(value)) {
1670
- assert (!isa<ModuleDecl>(typeDecl) && " Nested module?" );
1671
-
1672
- auto memberTy = TypeChecker::substMemberTypeWithBase (typeDecl, baseObjTy);
1673
-
1674
- // If the member type is a constraint, e.g. because the
1675
- // reference is to a typealias with an underlying protocol
1676
- // or composition type, the member reference has existential
1677
- // type.
1678
- if (memberTy->isConstraintType ())
1679
- memberTy = ExistentialType::get (memberTy);
1680
-
1681
- checkNestedTypeConstraints (*this , memberTy, locator, preparedOverload);
1682
-
1683
- // Convert any placeholders and open any generics.
1684
- memberTy = replaceInferableTypesWithTypeVars (
1685
- memberTy, locator, preparedOverload);
1686
-
1687
- // Wrap it in a metatype, unless this is a value generic.
1688
- // 'substMemberTypeWithBase' returns the underlying value type
1689
- // of the value generic (e.g. 'Int').
1690
- if (!isa<GenericTypeParamDecl>(value) ||
1691
- !cast<GenericTypeParamDecl>(value)->isValue ()) {
1692
- memberTy = MetatypeType::get (memberTy);
1693
- }
1694
-
1695
- FunctionType::Param baseObjParam (baseObjTy);
1696
- auto openedType = FunctionType::get ({baseObjParam}, memberTy);
1697
- return { openedType, openedType, memberTy, memberTy, Type () };
1777
+ return getTypeOfMemberTypeReference (baseObjTy, typeDecl,
1778
+ locator, preparedOverload);
1698
1779
}
1699
1780
1700
1781
// Figure out the declaration context to use when opening this type.
@@ -1704,7 +1785,6 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1704
1785
auto genericSig = innerDC->getGenericSignatureOfContext ();
1705
1786
1706
1787
// Open the type of the generic function or member of a generic type.
1707
- Type openedType;
1708
1788
ArrayRef<OpenedType> replacements;
1709
1789
SmallVector<OpenedType, 4 > localReplacements;
1710
1790
{
@@ -1731,6 +1811,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1731
1811
// strip it off later.
1732
1812
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf (baseRValueTy, value);
1733
1813
1814
+ Type openedType;
1734
1815
Type thrownErrorType;
1735
1816
if (isa<AbstractFunctionDecl>(value) ||
1736
1817
isa<EnumElementDecl>(value) ||
@@ -1755,77 +1836,18 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1755
1836
});
1756
1837
}
1757
1838
} else {
1758
- // If the storage has a throwing getter, save the thrown error type..
1759
- auto storage = cast<AbstractStorageDecl>(value);
1760
- if (auto accessor = storage->getEffectfulGetAccessor ()) {
1761
- thrownErrorType = accessor->getEffectiveThrownErrorType ().value_or (Type ());
1762
- }
1839
+ auto *storage = cast<AbstractStorageDecl>(value);
1763
1840
1764
- // For a property, build a type (Self) -> PropType.
1765
- // For a subscript, build a type (Self) -> (Indices...) throws(?) -> ElementType.
1766
- //
1767
- // If the access is mutating, wrap the storage type in an lvalue type.
1768
- Type refType;
1769
- if (auto *subscript = dyn_cast<SubscriptDecl>(value)) {
1770
- auto elementTy = subscript->getElementInterfaceType ();
1771
-
1772
- if (doesStorageProduceLValue (subscript, baseTy, useDC, *this , locator))
1773
- elementTy = LValueType::get (elementTy);
1774
-
1775
- auto indices = subscript->getInterfaceType ()
1776
- ->castTo <AnyFunctionType>()->getParams ();
1777
-
1778
- // Transfer the thrown error type into the subscript reference type,
1779
- // which will be used in the application.
1780
- FunctionType::ExtInfo info;
1781
- if (thrownErrorType) {
1782
- info = info.withThrows (true , thrownErrorType);
1783
- thrownErrorType = Type ();
1784
- }
1785
-
1786
- refType = FunctionType::get (indices, elementTy, info);
1787
- } else {
1788
- // Delay the adjustment for preconcurrency until after we've formed
1789
- // the function type for this kind of reference. Otherwise we will lose
1790
- // track of the adjustment in the formed function's return type.
1791
-
1792
- refType = getUnopenedTypeOfReference (cast<VarDecl>(value), baseTy, useDC,
1793
- locator,
1794
- /* wantInterfaceType=*/ true );
1795
- }
1796
-
1797
- auto selfTy = outerDC->getSelfInterfaceType ();
1798
-
1799
- // If this is a reference to an instance member that applies self,
1800
- // where self is a value type and the base type is an lvalue, wrap it in an
1801
- // inout type.
1802
- auto selfFlags = ParameterTypeFlags ();
1803
- if (value->isInstanceMember () && hasAppliedSelf &&
1804
- !outerDC->getDeclaredInterfaceType ()->hasReferenceSemantics () &&
1805
- baseTy->is <LValueType>() &&
1806
- !selfTy->hasError ())
1807
- selfFlags = selfFlags.withInOut (true );
1808
-
1809
- // If the storage is generic, open the self and ref types.
1810
- if (genericSig) {
1811
- selfTy = openType (selfTy, replacements, locator, preparedOverload);
1812
- refType = openType (refType, replacements, locator, preparedOverload);
1813
-
1814
- if (thrownErrorType) {
1815
- thrownErrorType = openType (thrownErrorType, replacements, locator,
1816
- preparedOverload);
1817
- }
1818
- }
1819
- FunctionType::Param selfParam (selfTy, Identifier (), selfFlags);
1820
-
1821
- FunctionType::ExtInfo info;
1822
- openedType = FunctionType::get ({selfParam}, refType, info);
1841
+ std::tie (thrownErrorType, openedType) = getOpenedStorageType (
1842
+ baseTy, storage, useDC, hasAppliedSelf, replacements, locator,
1843
+ preparedOverload);
1823
1844
}
1824
- assert (!openedType->hasTypeParameter ());
1825
1845
1846
+ ASSERT (!openedType->hasTypeParameter ());
1847
+
1848
+ // Remove argument labels if this is an unapplied reference.
1826
1849
unsigned numRemovedArgumentLabels = getNumRemovedArgumentLabels (
1827
1850
value, /* isCurriedInstanceReference*/ !hasAppliedSelf, functionRefInfo);
1828
-
1829
1851
openedType = openedType->removeArgumentLabels (numRemovedArgumentLabels);
1830
1852
1831
1853
Type baseOpenedTy = baseObjTy;
@@ -1897,6 +1919,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1897
1919
}, preparedOverload);
1898
1920
}
1899
1921
1922
+ // Unwrap property wrappers if this is an unapplied reference.
1900
1923
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(value)) {
1901
1924
if (functionRefInfo.isUnapplied ()) {
1902
1925
auto *fullFunctionType = openedType->getAs <AnyFunctionType>();
@@ -1938,24 +1961,24 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
1938
1961
origFnType->getParams (), resultTy, origFnType->getExtInfo ());
1939
1962
}
1940
1963
1941
- // Check if we need to apply a layer of optionality to the uncurried type.
1964
+ // Check if we need to apply a layer of optionality to the type.
1942
1965
if (!isRequirementOrWitness (locator)) {
1943
1966
if (isDynamicLookup || value->getAttrs ().hasAttribute <OptionalAttr>()) {
1944
1967
openedType = applyOptionality (value, openedType->castTo <FunctionType>());
1945
1968
origOpenedType = applyOptionality (value, origOpenedType->castTo <FunctionType>());
1946
1969
}
1947
1970
}
1948
1971
1949
- // Compute the type of the reference .
1972
+ // Handle DynamicSelfType and a couple of other things .
1950
1973
Type type = getMemberReferenceTypeFromOpenedType (
1951
- openedType, baseObjTy, value, outerDC, locator, hasAppliedSelf,
1974
+ openedType, baseObjTy, value, locator, hasAppliedSelf,
1952
1975
isDynamicLookup, replacements);
1953
1976
1954
1977
// Do the same thing for the original type, if there can be any difference.
1955
1978
Type origType = type;
1956
1979
if (openedType.getPointer () != origOpenedType.getPointer ()) {
1957
1980
origType = getMemberReferenceTypeFromOpenedType (
1958
- origOpenedType, baseObjTy, value, outerDC, locator, hasAppliedSelf,
1981
+ origOpenedType, baseObjTy, value, locator, hasAppliedSelf,
1959
1982
isDynamicLookup, replacements);
1960
1983
}
1961
1984
0 commit comments