Skip to content

Commit 68be47f

Browse files
committed
Sema: Re-organize some logic in getTypeOfMemberReference()
1 parent a7cbe5c commit 68be47f

File tree

2 files changed

+40
-42
lines changed

2 files changed

+40
-42
lines changed

lib/Sema/TypeOfReference.cpp

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,33 +1658,14 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
16581658

16591659
// Figure out the instance type used for the base.
16601660
Type baseRValueTy = baseTy->getRValueType();
1661+
auto baseObjTy = baseRValueTy->getMetatypeInstanceType();
16611662

16621663
// If the base is a module type, just use the type of the decl.
1663-
if (baseRValueTy->is<ModuleType>()) {
1664+
if (baseObjTy->is<ModuleType>()) {
16641665
return getTypeOfReference(value, functionRefInfo, locator, useDC,
16651666
preparedOverload);
16661667
}
16671668

1668-
// Check to see if the self parameter is applied, in which case we'll want to
1669-
// strip it off later.
1670-
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseRValueTy, value);
1671-
1672-
auto baseObjTy = baseRValueTy->getMetatypeInstanceType();
1673-
FunctionType::Param baseObjParam(baseObjTy);
1674-
1675-
// Indicates whether this is a valid reference to a static member on a
1676-
// protocol metatype. Such a reference is only valid if performed through
1677-
// leading dot syntax e.g. `foo(.bar)` where implicit base is a protocol
1678-
// metatype and `bar` is static member declared in a protocol or its
1679-
// extension.
1680-
bool isStaticMemberRefOnProtocol = false;
1681-
if (baseObjTy->isExistentialType() && value->isStatic() &&
1682-
locator->isLastElement<LocatorPathElt::UnresolvedMember>()) {
1683-
assert(baseRValueTy->is<MetatypeType>() &&
1684-
"Assumed base of unresolved member access must be a metatype");
1685-
isStaticMemberRefOnProtocol = true;
1686-
}
1687-
16881669
if (auto *typeDecl = dyn_cast<TypeDecl>(value)) {
16891670
assert(!isa<ModuleDecl>(typeDecl) && "Nested module?");
16901671

@@ -1711,6 +1692,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
17111692
memberTy = MetatypeType::get(memberTy);
17121693
}
17131694

1695+
FunctionType::Param baseObjParam(baseObjTy);
17141696
auto openedType = FunctionType::get({baseObjParam}, memberTy);
17151697
return { openedType, openedType, memberTy, memberTy, Type() };
17161698
}
@@ -1745,6 +1727,10 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
17451727
replacements = _replacements;
17461728
}
17471729

1730+
// Check to see if the self parameter is applied, in which case we'll want to
1731+
// strip it off later.
1732+
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseRValueTy, value);
1733+
17481734
Type thrownErrorType;
17491735
if (isa<AbstractFunctionDecl>(value) ||
17501736
isa<EnumElementDecl>(value) ||
@@ -1842,30 +1828,42 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
18421828

18431829
openedType = openedType->removeArgumentLabels(numRemovedArgumentLabels);
18441830

1845-
// If we are looking at a member of an existential, open the existential.
18461831
Type baseOpenedTy = baseObjTy;
18471832

1848-
if (isStaticMemberRefOnProtocol) {
1849-
// In diagnostic mode, let's not try to replace base type
1850-
// if there is already a known issue associated with this
1851-
// reference e.g. it might be incorrect initializer call
1852-
// or result type is invalid.
1853-
if (!(shouldAttemptFixes() && hasFixFor(getConstraintLocator(locator)))) {
1854-
if (auto concreteSelf =
1855-
getConcreteReplacementForProtocolSelfType(value)) {
1856-
// Concrete type replacing `Self` could be generic, so we need
1857-
// to make sure that it's opened before use.
1858-
baseOpenedTy = openType(concreteSelf, replacements, locator,
1859-
preparedOverload);
1860-
baseObjTy = baseOpenedTy;
1833+
// If we are looking at a member of an existential, open the existential.
1834+
if (baseObjTy->isExistentialType()) {
1835+
if (value->isStatic() &&
1836+
locator->isLastElement<LocatorPathElt::UnresolvedMember>()) {
1837+
// Indicates whether this is a valid reference to a static member on a
1838+
// protocol metatype. Such a reference is only valid if performed through
1839+
// leading dot syntax e.g. `foo(.bar)` where implicit base is a protocol
1840+
// metatype and `bar` is static member declared in a protocol or its
1841+
// extension.
1842+
assert(baseRValueTy->is<MetatypeType>() &&
1843+
"Assumed base of unresolved member access must be a metatype");
1844+
1845+
// In diagnostic mode, let's not try to replace base type
1846+
// if there is already a known issue associated with this
1847+
// reference e.g. it might be incorrect initializer call
1848+
// or result type is invalid.
1849+
if (!(shouldAttemptFixes() && hasFixFor(getConstraintLocator(locator)))) {
1850+
if (auto concreteSelf =
1851+
getConcreteReplacementForProtocolSelfType(value)) {
1852+
// Concrete type replacing `Self` could be generic, so we need
1853+
// to make sure that it's opened before use.
1854+
baseOpenedTy = openType(concreteSelf, replacements, locator,
1855+
preparedOverload);
1856+
baseObjTy = baseOpenedTy;
1857+
}
18611858
}
1859+
} else {
1860+
// Open the existential.
1861+
auto openedArchetype =
1862+
ExistentialArchetypeType::get(baseObjTy->getCanonicalType());
1863+
recordOpenedExistentialType(getConstraintLocator(locator), openedArchetype,
1864+
preparedOverload);
1865+
baseOpenedTy = openedArchetype;
18621866
}
1863-
} else if (baseObjTy->isExistentialType()) {
1864-
auto openedArchetype =
1865-
ExistentialArchetypeType::get(baseObjTy->getCanonicalType());
1866-
recordOpenedExistentialType(getConstraintLocator(locator), openedArchetype,
1867-
preparedOverload);
1868-
baseOpenedTy = openedArchetype;
18691867
}
18701868

18711869
// Constrain the 'self' object type.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// {"kind":"typecheck","signature":"swift::constraints::doesMemberRefApplyCurriedSelf(swift::Type, swift::ValueDecl const*)","signatureAssert":"Assertion failed: (decl->getDeclContext()->isTypeContext() && \"Expected a member reference\"), function doesMemberRefApplyCurriedSelf"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
Swift < .Int

0 commit comments

Comments
 (0)