Skip to content

Commit 1063e81

Browse files
committed
[Constraint system] Track the original opened type for a selected overload.
1 parent 045df94 commit 1063e81

File tree

5 files changed

+93
-68
lines changed

5 files changed

+93
-68
lines changed

include/swift/Sema/ConstraintSystem.h

+28-6
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,10 @@ struct SelectedOverload {
658658
/// we're referencing a member.
659659
const Type openedFullType;
660660

661+
/// The opened type of the base of the reference to this overload, adjusted
662+
/// for `@preconcurrency` or other contextual type-altering attributes.
663+
const Type adjustedOpenedFullType;
664+
661665
/// The opened type produced by referring to this overload.
662666
const Type openedType;
663667

@@ -2515,6 +2519,26 @@ struct GetClosureType {
25152519
Type operator()(const AbstractClosureExpr *expr) const;
25162520
};
25172521

2522+
/// Describes the type produced when referencing a declaration.
2523+
struct DeclReferenceType {
2524+
/// The "opened" type, which is the type of the declaration where any
2525+
/// generic parameters have been replaced with type variables.
2526+
///
2527+
/// The mapping from generic parameters to type variables will have been
2528+
/// recorded by \c recordOpenedTypes when this type is produced.
2529+
Type openedType;
2530+
2531+
/// The opened type, after performing contextual type adjustments such as
2532+
/// removing concurrency-related annotations for a `@preconcurrency`
2533+
/// operation.
2534+
Type adjustedOpenedType;
2535+
2536+
/// The type of the reference, which is the adjusted opened type after
2537+
/// (e.g.) applying the base of a member access. This is the type of the
2538+
/// expression used to form the declaration reference type.
2539+
Type referenceType;
2540+
};
2541+
25182542
/// Describes a system of constraints on type variables, the
25192543
/// solution of which assigns concrete types to each of the type variables.
25202544
/// Constraint systems are typically generated given an (untyped) expression.
@@ -4481,9 +4505,8 @@ class ConstraintSystem {
44814505
///
44824506
/// \param decl The declarations whose type is being computed.
44834507
///
4484-
/// \returns a pair containing the full opened type (if applicable) and
4485-
/// opened type of a reference to declaration.
4486-
std::pair<Type, Type> getTypeOfReference(
4508+
/// \returns a description of the type of this declaration reference.
4509+
DeclReferenceType getTypeOfReference(
44874510
ValueDecl *decl,
44884511
FunctionRefKind functionRefKind,
44894512
ConstraintLocatorBuilder locator,
@@ -4541,9 +4564,8 @@ class ConstraintSystem {
45414564
/// \param isDynamicResult Indicates that this declaration was found via
45424565
/// dynamic lookup.
45434566
///
4544-
/// \returns a pair containing the full opened type (which includes the opened
4545-
/// base) and opened type of a reference to this member.
4546-
std::pair<Type, Type> getTypeOfMemberReference(
4567+
/// \returns a description of the type of this declaration reference.
4568+
DeclReferenceType getTypeOfMemberReference(
45474569
Type baseTy, ValueDecl *decl, DeclContext *useDC,
45484570
bool isDynamicResult,
45494571
FunctionRefKind functionRefKind,

lib/Sema/CSApply.cpp

+14-14
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;
@@ -3099,7 +3099,7 @@ namespace {
30993099

31003100
// Build a partial application of the delegated initializer.
31013101
auto callee = resolveConcreteDeclRef(ctor, ctorLocator);
3102-
Expr *ctorRef = buildOtherConstructorRef(overload.openedFullType, callee,
3102+
Expr *ctorRef = buildOtherConstructorRef(overload.adjustedOpenedFullType, callee,
31033103
base, nameLoc, ctorLocator,
31043104
implicit);
31053105
auto *call =
@@ -3322,7 +3322,7 @@ namespace {
33223322
Type getTypeOfDynamicMemberIndex(const SelectedOverload &overload) {
33233323
assert(overload.choice.isAnyDynamicMemberLookup());
33243324

3325-
auto declTy = solution.simplifyType(overload.openedFullType);
3325+
auto declTy = solution.simplifyType(overload.adjustedOpenedFullType);
33263326
auto subscriptTy = declTy->castTo<FunctionType>()->getResult();
33273327
auto refFnType = subscriptTy->castTo<FunctionType>();
33283328
assert(refFnType->getParams().size() == 1 &&

lib/Sema/CSDiagnostics.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2216,7 +2216,7 @@ AssignmentFailure::getMemberRef(ConstraintLocator *locator) const {
22162216
if (isValidKeyPathDynamicMemberLookup(subscript)) {
22172217
// Type has a following format:
22182218
// `(Self) -> (dynamicMember: {Writable}KeyPath<T, U>) -> U`
2219-
auto *fullType = member->openedFullType->castTo<FunctionType>();
2219+
auto *fullType = member->adjustedOpenedFullType->castTo<FunctionType>();
22202220
auto *fnType = fullType->getResult()->castTo<FunctionType>();
22212221

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

0 commit comments

Comments
 (0)