Skip to content

Commit a1abcee

Browse files
committed
[CS] Introduce ConstructorMemberType locator elt
Use this new element to represent the overload type for a constructor call, and have it store a bit indicating whether the call is for a short-form `X(...)` or self-delegating `self.init(...)` call.
1 parent 0ecd4ff commit a1abcee

File tree

5 files changed

+56
-12
lines changed

5 files changed

+56
-12
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,25 @@ class LocatorPathElt::KeyPathType final
960960
}
961961
};
962962

963+
class LocatorPathElt::ConstructorMemberType final
964+
: public StoredIntegerElement<1> {
965+
public:
966+
ConstructorMemberType(bool isShortFormOrSelfDelegating = false)
967+
: StoredIntegerElement(ConstraintLocator::ConstructorMemberType,
968+
isShortFormOrSelfDelegating) {}
969+
970+
/// Whether this constructor overload is for a short-form init call such as
971+
/// 'X(...)', or a 'self.init(...)' call. Such calls have additional ranking
972+
/// rules.
973+
bool isShortFormOrSelfDelegatingConstructor() const {
974+
return bool(getValue());
975+
}
976+
977+
static bool classof(const LocatorPathElt *elt) {
978+
return elt->getKind() == ConstraintLocator::ConstructorMemberType;
979+
}
980+
};
981+
963982
class LocatorPathElt::ClosureBodyElement final
964983
: public StoredPointerElement<void> {
965984
public:

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ CUSTOM_LOCATOR_PATH_ELT(ClosureBody)
6060
/// The lookup for a constructor member.
6161
SIMPLE_LOCATOR_PATH_ELT(ConstructorMember)
6262

63+
/// The constructor member type in the lookup of a constructor.
64+
CUSTOM_LOCATOR_PATH_ELT(ConstructorMemberType)
65+
6366
/// The desired contextual type passed in to the constraint system.
6467
CUSTOM_LOCATOR_PATH_ELT(ContextualType)
6568

lib/Sema/CSGen.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,8 +1214,14 @@ namespace {
12141214
auto *memberLoc =
12151215
CS.getConstraintLocator(expr, ConstraintLocator::ConstructorMember);
12161216

1217+
auto *fnLoc =
1218+
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction);
1219+
1220+
auto *memberTypeLoc = CS.getConstraintLocator(
1221+
fnLoc, LocatorPathElt::ConstructorMemberType());
1222+
12171223
auto *memberType =
1218-
CS.createTypeVariable(memberLoc, TVO_CanBindToNoEscape);
1224+
CS.createTypeVariable(memberTypeLoc, TVO_CanBindToNoEscape);
12191225

12201226
CS.addValueMemberConstraint(MetatypeType::get(witnessType, ctx),
12211227
DeclNameRef(constrName), memberType, CurDC,
@@ -1228,10 +1234,9 @@ namespace {
12281234
CS.getConstraintLocator(expr, ConstraintLocator::FunctionResult),
12291235
TVO_CanBindToNoEscape);
12301236

1231-
CS.addConstraint(
1232-
ConstraintKind::ApplicableFunction,
1233-
FunctionType::get(params, resultType), memberType,
1234-
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction));
1237+
CS.addConstraint(ConstraintKind::ApplicableFunction,
1238+
FunctionType::get(params, resultType), memberType,
1239+
fnLoc);
12351240

12361241
if (constr->isFailable())
12371242
return OptionalType::get(witnessType);
@@ -1500,10 +1505,12 @@ namespace {
15001505
// self.super = Super.init()
15011506
baseTy = MetatypeType::get(baseTy, ctx);
15021507

1503-
auto methodTy = CS.createTypeVariable(
1504-
CS.getConstraintLocator(expr,
1505-
ConstraintLocator::ApplyFunction),
1506-
TVO_CanBindToNoEscape);
1508+
auto memberTypeLoc = CS.getConstraintLocator(
1509+
expr, LocatorPathElt::ConstructorMemberType(
1510+
/*shortFormOrSelfDelegating*/ true));
1511+
1512+
auto methodTy =
1513+
CS.createTypeVariable(memberTypeLoc, TVO_CanBindToNoEscape);
15071514

15081515
// FIXME: Once TVO_PrefersSubtypeBinding is replaced with something
15091516
// better, we won't need the second type variable at all.

lib/Sema/CSSimplify.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6214,8 +6214,11 @@ ConstraintSystem::simplifyConstructionConstraint(
62146214

62156215
auto fnLocator = getConstraintLocator(locator,
62166216
ConstraintLocator::ApplyFunction);
6217-
auto memberType = createTypeVariable(fnLocator,
6218-
TVO_CanBindToNoEscape);
6217+
auto memberTypeLoc =
6218+
getConstraintLocator(fnLocator, LocatorPathElt::ConstructorMemberType(
6219+
/*shortFormOrSelfDelegating*/ true));
6220+
6221+
auto memberType = createTypeVariable(memberTypeLoc, TVO_CanBindToNoEscape);
62196222

62206223
// The constructor will have function type T -> T2, for a fresh type
62216224
// variable T. T2 is the result type provided via the construction
@@ -11338,7 +11341,10 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1133811341
ArgumentLists.insert({memberLoc, argList});
1133911342
}
1134011343

11341-
auto *memberTy = createTypeVariable(memberLoc, TVO_CanBindToNoEscape);
11344+
auto *memberTypeLoc = getConstraintLocator(
11345+
applicationLoc, LocatorPathElt::ConstructorMemberType());
11346+
11347+
auto *memberTy = createTypeVariable(memberTypeLoc, TVO_CanBindToNoEscape);
1134211348

1134311349
addValueMemberConstraint(MetatypeType::get(type2, getASTContext()),
1134411350
DeclNameRef(DeclBaseName::createConstructor()),

lib/Sema/ConstraintLocator.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ unsigned LocatorPathElt::getNewSummaryFlags() const {
4747
case ConstraintLocator::ClosureResult:
4848
case ConstraintLocator::ClosureBody:
4949
case ConstraintLocator::ConstructorMember:
50+
case ConstraintLocator::ConstructorMemberType:
5051
case ConstraintLocator::ResultBuilderBodyResult:
5152
case ConstraintLocator::InstanceType:
5253
case ConstraintLocator::AutoclosureResult:
@@ -322,6 +323,14 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) const {
322323
out << "constructor member";
323324
break;
324325

326+
case ConstructorMemberType: {
327+
auto memberTypeElt = elt.castTo<LocatorPathElt::ConstructorMemberType>();
328+
out << "constructor member type";
329+
if (memberTypeElt.isShortFormOrSelfDelegatingConstructor())
330+
out << " (for short-form or self.init call)";
331+
break;
332+
}
333+
325334
case FunctionArgument:
326335
out << "function argument";
327336
break;

0 commit comments

Comments
 (0)