Skip to content

Commit 6d33173

Browse files
committed
[Constraint system] Track the original opened type for a selected overload.
1 parent 7c00af5 commit 6d33173

File tree

5 files changed

+93
-68
lines changed

5 files changed

+93
-68
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,10 @@ struct SelectedOverload {
614614
/// we're referencing a member.
615615
const Type openedFullType;
616616

617+
/// The opened type of the base of the reference to this overload, adjusted
618+
/// for `@preconcurrency` or other contextual type-altering attributes.
619+
const Type adjustedOpenedFullType;
620+
617621
/// The opened type produced by referring to this overload.
618622
const Type openedType;
619623

@@ -2471,6 +2475,26 @@ struct GetClosureType {
24712475
Type operator()(const AbstractClosureExpr *expr) const;
24722476
};
24732477

2478+
/// Describes the type produced when referencing a declaration.
2479+
struct DeclReferenceType {
2480+
/// The "opened" type, which is the type of the declaration where any
2481+
/// generic parameters have been replaced with type variables.
2482+
///
2483+
/// The mapping from generic parameters to type variables will have been
2484+
/// recorded by \c recordOpenedTypes when this type is produced.
2485+
Type openedType;
2486+
2487+
/// The opened type, after performing contextual type adjustments such as
2488+
/// removing concurrency-related annotations for a `@preconcurrency`
2489+
/// operation.
2490+
Type adjustedOpenedType;
2491+
2492+
/// The type of the reference, which is the adjusted opened type after
2493+
/// (e.g.) applying the base of a member access. This is the type of the
2494+
/// expression used to form the declaration reference type.
2495+
Type referenceType;
2496+
};
2497+
24742498
/// Describes a system of constraints on type variables, the
24752499
/// solution of which assigns concrete types to each of the type variables.
24762500
/// Constraint systems are typically generated given an (untyped) expression.
@@ -4437,9 +4461,8 @@ class ConstraintSystem {
44374461
///
44384462
/// \param decl The declarations whose type is being computed.
44394463
///
4440-
/// \returns a pair containing the full opened type (if applicable) and
4441-
/// opened type of a reference to declaration.
4442-
std::pair<Type, Type> getTypeOfReference(
4464+
/// \returns a description of the type of this declaration reference.
4465+
DeclReferenceType getTypeOfReference(
44434466
ValueDecl *decl,
44444467
FunctionRefKind functionRefKind,
44454468
ConstraintLocatorBuilder locator,
@@ -4497,9 +4520,8 @@ class ConstraintSystem {
44974520
/// \param isDynamicResult Indicates that this declaration was found via
44984521
/// dynamic lookup.
44994522
///
4500-
/// \returns a pair containing the full opened type (which includes the opened
4501-
/// base) and opened type of a reference to this member.
4502-
std::pair<Type, Type> getTypeOfMemberReference(
4523+
/// \returns a description of the type of this declaration reference.
4524+
DeclReferenceType getTypeOfMemberReference(
45034525
Type baseTy, ValueDecl *decl, DeclContext *useDC,
45044526
bool isDynamicResult,
45054527
FunctionRefKind functionRefKind,

lib/Sema/CSApply.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ namespace {
527527
auto choice = overload.choice;
528528
assert(choice.getKind() != OverloadChoiceKind::DeclViaDynamic);
529529
auto *decl = choice.getDecl();
530-
auto fullType = simplifyType(overload.openedFullType);
530+
auto fullType = simplifyType(overload.adjustedOpenedFullType);
531531

532532
// Determine the declaration selected for this overloaded reference.
533533
auto &ctx = cs.getASTContext();
@@ -1388,7 +1388,7 @@ namespace {
13881388
ConstraintLocatorBuilder memberLocator, bool Implicit,
13891389
AccessSemantics semantics) {
13901390
const auto &choice = overload.choice;
1391-
const auto openedType = overload.openedType;
1391+
const auto adjustedOpenedType = overload.openedType;
13921392

13931393
ValueDecl *member = choice.getDecl();
13941394

@@ -1433,7 +1433,7 @@ namespace {
14331433
if (!isExistentialMetatype && baseTy->is<ProtocolType>() &&
14341434
member->isStatic()) {
14351435
auto selfParam =
1436-
overload.openedFullType->castTo<FunctionType>()->getParams()[0];
1436+
overload.adjustedOpenedFullType->castTo<FunctionType>()->getParams()[0];
14371437

14381438
Type baseTy =
14391439
simplifyType(selfParam.getPlainType())->getMetatypeInstanceType();
@@ -1449,7 +1449,7 @@ namespace {
14491449
// If we're referring to a member type, it's just a type
14501450
// reference.
14511451
if (auto *TD = dyn_cast<TypeDecl>(member)) {
1452-
Type refType = simplifyType(openedType);
1452+
Type refType = simplifyType(adjustedOpenedType);
14531453
auto ref = TypeExpr::createForDecl(memberLoc, TD, dc);
14541454
cs.setType(ref, refType);
14551455
auto *result = new (context) DotSyntaxBaseIgnoredExpr(
@@ -1458,7 +1458,7 @@ namespace {
14581458
return result;
14591459
}
14601460

1461-
auto refTy = simplifyType(overload.openedFullType);
1461+
auto refTy = simplifyType(overload.adjustedOpenedFullType);
14621462

14631463
// If we're referring to the member of a module, it's just a simple
14641464
// reference.
@@ -1596,7 +1596,7 @@ namespace {
15961596
// FIXME: FunctionRefKind
15971597

15981598
// Compute the type of the reference.
1599-
Type refType = simplifyType(openedType);
1599+
Type refType = simplifyType(adjustedOpenedType);
16001600

16011601
// If the base was an opened existential, erase the opened
16021602
// existential.
@@ -1649,7 +1649,7 @@ namespace {
16491649
// type having 'Self' swapped for the appropriate replacement
16501650
// type -- usually the base object type.
16511651
if (hasDynamicSelf) {
1652-
const auto conversionTy = simplifyType(openedType);
1652+
const auto conversionTy = simplifyType(adjustedOpenedType);
16531653
if (!containerTy->isEqual(conversionTy)) {
16541654
result = cs.cacheType(new (context) CovariantReturnConversionExpr(
16551655
result, conversionTy));
@@ -1724,7 +1724,7 @@ namespace {
17241724
// must be downcast to the opened archetype before being erased to the
17251725
// subclass existential to cope with the expectations placed
17261726
// on 'CovariantReturnConversionExpr'.
1727-
curryThunkTy = simplifyType(openedType)->castTo<FunctionType>();
1727+
curryThunkTy = simplifyType(adjustedOpenedType)->castTo<FunctionType>();
17281728
} else {
17291729
curryThunkTy = refTy->castTo<FunctionType>();
17301730

@@ -1789,7 +1789,7 @@ namespace {
17891789
ref = forceUnwrapIfExpected(ref, memberLocator);
17901790
apply = ConstructorRefCallExpr::create(context, ref, base);
17911791
} else if (isUnboundInstanceMember) {
1792-
auto refType = cs.simplifyType(openedType);
1792+
auto refType = cs.simplifyType(adjustedOpenedType);
17931793
if (!cs.getType(ref)->isEqual(refType)) {
17941794
ref = new (context) FunctionConversionExpr(ref, refType);
17951795
cs.cacheType(ref);
@@ -1812,7 +1812,7 @@ namespace {
18121812
}
18131813
}
18141814

1815-
return finishApply(apply, openedType, locator, memberLocator);
1815+
return finishApply(apply, adjustedOpenedType, locator, memberLocator);
18161816
}
18171817

18181818
/// Convert the given literal expression via a protocol pair.
@@ -2072,7 +2072,7 @@ namespace {
20722072
auto subscriptRef = resolveConcreteDeclRef(subscript, memberLoc);
20732073

20742074
// Coerce the index argument.
2075-
auto openedFullFnType = simplifyType(selected.openedFullType)
2075+
auto openedFullFnType = simplifyType(selected.adjustedOpenedFullType)
20762076
->castTo<FunctionType>();
20772077
auto fullSubscriptTy = openedFullFnType->getResult()
20782078
->castTo<FunctionType>();
@@ -2098,7 +2098,7 @@ namespace {
20982098
auto resultTy = simplifyType(selected.openedType)
20992099
->castTo<FunctionType>()
21002100
->getResult();
2101-
assert(!selected.openedFullType->hasOpenedExistential()
2101+
assert(!selected.adjustedOpenedFullType->hasOpenedExistential()
21022102
&& "open existential archetype in AnyObject subscript type?");
21032103
cs.setType(subscriptExpr, resultTy);
21042104
Expr *result = subscriptExpr;
@@ -3085,7 +3085,7 @@ namespace {
30853085

30863086
// Build a partial application of the delegated initializer.
30873087
auto callee = resolveConcreteDeclRef(ctor, ctorLocator);
3088-
Expr *ctorRef = buildOtherConstructorRef(overload.openedFullType, callee,
3088+
Expr *ctorRef = buildOtherConstructorRef(overload.adjustedOpenedFullType, callee,
30893089
base, nameLoc, ctorLocator,
30903090
implicit);
30913091
auto *call =
@@ -3308,7 +3308,7 @@ namespace {
33083308
Type getTypeOfDynamicMemberIndex(const SelectedOverload &overload) {
33093309
assert(overload.choice.isAnyDynamicMemberLookup());
33103310

3311-
auto declTy = solution.simplifyType(overload.openedFullType);
3311+
auto declTy = solution.simplifyType(overload.adjustedOpenedFullType);
33123312
auto subscriptTy = declTy->castTo<FunctionType>()->getResult();
33133313
auto refFnType = subscriptTy->castTo<FunctionType>();
33143314
assert(refFnType->getParams().size() == 1 &&

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,7 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
22032203
if (isValidKeyPathDynamicMemberLookup(subscript)) {
22042204
// Type has a following format:
22052205
// `(Self) -> (dynamicMember: {Writable}KeyPath<T, U>) -> U`
2206-
auto *fullType = member->openedFullType->castTo<FunctionType>();
2206+
auto *fullType = member->adjustedOpenedFullType->castTo<FunctionType>();
22072207
auto *fnType = fullType->getResult()->castTo<FunctionType>();
22082208

22092209
auto paramTy = fnType->getParams()[0].getPlainType();

0 commit comments

Comments
 (0)