Skip to content

Commit 755e7bd

Browse files
committed
Track the pre-adjusted "reference" type for declaration reference.
1 parent 6d33173 commit 755e7bd

File tree

8 files changed

+236
-187
lines changed

8 files changed

+236
-187
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,12 @@ struct SelectedOverload {
621621
/// The opened type produced by referring to this overload.
622622
const Type openedType;
623623

624+
/// The opened type produced by referring to this overload, adjusted for
625+
/// `@preconcurrency` or other contextual type-altering attributes.
626+
const Type adjustedOpenedType;
627+
624628
/// The type that this overload binds. Note that this may differ from
625-
/// openedType, for example it will include any IUO unwrapping that has taken
629+
/// adjustedOpenedType, for example it will include any IUO unwrapping that has taken
626630
/// place.
627631
const Type boundType;
628632
};
@@ -2489,10 +2493,15 @@ struct DeclReferenceType {
24892493
/// operation.
24902494
Type adjustedOpenedType;
24912495

2496+
/// The type of the reference, based on the original opened type. This is the
2497+
/// type that the expression used to form the declaration reference would
2498+
/// have if no adjustments had been applied.
2499+
Type referenceType;
2500+
24922501
/// The type of the reference, which is the adjusted opened type after
24932502
/// (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;
2503+
/// expression used to form the declaration reference.
2504+
Type adjustedReferenceType;
24962505
};
24972506

24982507
/// Describes a system of constraints on type variables, the
@@ -4510,6 +4519,14 @@ class ConstraintSystem {
45104519
return Type();
45114520
});
45124521

4522+
/// Given the opened type and a pile of information about a member reference,
4523+
/// determine the reference type of the member reference.
4524+
Type getMemberReferenceTypeFromOpenedType(
4525+
Type &openedType, Type baseObjTy, ValueDecl *value, DeclContext *outerDC,
4526+
ConstraintLocator *locator, bool hasAppliedSelf,
4527+
bool isStaticMemberRefOnProtocol, bool isDynamicResult,
4528+
OpenedTypeMap &replacements);
4529+
45134530
/// Retrieve the type of a reference to the given value declaration,
45144531
/// as a member with a base of the given type.
45154532
///

lib/Sema/CSApply.cpp

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ namespace {
13881388
ConstraintLocatorBuilder memberLocator, bool Implicit,
13891389
AccessSemantics semantics) {
13901390
const auto &choice = overload.choice;
1391-
const auto adjustedOpenedType = overload.openedType;
1391+
const auto adjustedOpenedType = overload.adjustedOpenedType;
13921392

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

@@ -1595,16 +1595,21 @@ namespace {
15951595
ref->setImplicit(Implicit);
15961596
// FIXME: FunctionRefKind
15971597

1598-
// Compute the type of the reference.
1599-
Type refType = simplifyType(adjustedOpenedType);
1598+
auto computeRefType = [&](Type openedType) {
1599+
// Compute the type of the reference.
1600+
Type refType = simplifyType(adjustedOpenedType);
16001601

1601-
// If the base was an opened existential, erase the opened
1602-
// existential.
1603-
if (openedExistential) {
1604-
refType = refType->typeEraseOpenedArchetypesWithRoot(
1605-
baseTy->castTo<OpenedArchetypeType>(), dc);
1606-
}
1602+
// If the base was an opened existential, erase the opened
1603+
// existential.
1604+
if (openedExistential) {
1605+
refType = refType->typeEraseOpenedArchetypesWithRoot(
1606+
baseTy->castTo<OpenedArchetypeType>(), dc);
1607+
}
1608+
1609+
return refType;
1610+
};
16071611

1612+
Type refType = computeRefType(adjustedOpenedType);
16081613
cs.setType(ref, refType);
16091614

16101615
closeExistentials(ref, locator, /*force=*/openedExistential);
@@ -1967,7 +1972,7 @@ namespace {
19671972
// Apply a key path if we have one.
19681973
if (choice.getKind() == OverloadChoiceKind::KeyPathApplication) {
19691974
auto applicationTy =
1970-
simplifyType(selected.openedType)->castTo<FunctionType>();
1975+
simplifyType(selected.adjustedOpenedType)->castTo<FunctionType>();
19711976

19721977
// The index argument should be (keyPath: KeyPath<Root, Value>).
19731978
// Dig the key path expression out of the arguments.
@@ -2095,7 +2100,7 @@ namespace {
20952100
// TODO: diagnose if semantics != AccessSemantics::Ordinary?
20962101
auto subscriptExpr = DynamicSubscriptExpr::create(
20972102
ctx, base, args, subscriptRef, isImplicit);
2098-
auto resultTy = simplifyType(selected.openedType)
2103+
auto resultTy = simplifyType(selected.adjustedOpenedType)
20992104
->castTo<FunctionType>()
21002105
->getResult();
21012106
assert(!selected.adjustedOpenedFullType->hasOpenedExistential()
@@ -2152,7 +2157,7 @@ namespace {
21522157
// base object type.
21532158
if (hasDynamicSelf) {
21542159
const auto conversionTy = simplifyType(
2155-
selected.openedType->castTo<FunctionType>()->getResult());
2160+
selected.adjustedOpenedType->castTo<FunctionType>()->getResult());
21562161

21572162
if (!containerTy->isEqual(conversionTy)) {
21582163
result = cs.cacheType(
@@ -2852,7 +2857,7 @@ namespace {
28522857
return nullptr;
28532858

28542859
auto fnType =
2855-
simplifyType(selectedOverload->openedType)->castTo<FunctionType>();
2860+
simplifyType(selectedOverload->adjustedOpenedType)->castTo<FunctionType>();
28562861

28572862
auto newArgs = coerceCallArguments(
28582863
expr->getArgs(), fnType, witness, /*applyExpr=*/nullptr,
@@ -5027,7 +5032,7 @@ namespace {
50275032
const SelectedOverload &overload, SourceLoc componentLoc,
50285033
ConstraintLocator *locator,
50295034
SmallVectorImpl<KeyPathExpr::Component> &components) {
5030-
auto resolvedTy = simplifyType(overload.openedType);
5035+
auto resolvedTy = simplifyType(overload.adjustedOpenedType);
50315036
if (auto *property = overload.choice.getDeclOrNull()) {
50325037
// Key paths can only refer to properties currently.
50335038
auto varDecl = cast<VarDecl>(property);
@@ -5088,7 +5093,7 @@ namespace {
50885093
}
50895094

50905095
auto subscriptType =
5091-
simplifyType(overload.openedType)->castTo<AnyFunctionType>();
5096+
simplifyType(overload.adjustedOpenedType)->castTo<AnyFunctionType>();
50925097
auto resolvedTy = subscriptType->getResult();
50935098

50945099
// Coerce the indices to the type the subscript expects.
@@ -5104,7 +5109,7 @@ namespace {
51045109

51055110
auto hashable = ctx.getProtocol(KnownProtocolKind::Hashable);
51065111

5107-
auto fnType = overload.openedType->castTo<FunctionType>();
5112+
auto fnType = overload.adjustedOpenedType->castTo<FunctionType>();
51085113
SmallVector<Identifier, 4> newLabels;
51095114
for (auto &param : fnType->getParams()) {
51105115
newLabels.push_back(param.getLabel());
@@ -7667,7 +7672,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
76677672
cs.getConstraintLocator(applyFunctionLoc))) {
76687673
auto *method = dyn_cast<FuncDecl>(selected->choice.getDecl());
76697674
auto methodType =
7670-
simplifyType(selected->openedType)->getAs<AnyFunctionType>();
7675+
simplifyType(selected->adjustedOpenedType)->getAs<AnyFunctionType>();
76717676
if (method && methodType) {
76727677
// Handle a call to a @dynamicCallable method.
76737678
if (isValidDynamicCallableMethod(method, methodType))

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,7 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
12961296
// only a '?' fixit) even though the constraint system didn't need to add any
12971297
// additional optionality.
12981298
auto overload = getOverloadChoiceIfAvailable(locator);
1299-
if (overload && overload->openedType->getOptionalObjectType())
1299+
if (overload && overload->adjustedOpenedType->getOptionalObjectType())
13001300
resultIsOptional = true;
13011301

13021302
auto unwrappedBaseType = baseType->getOptionalObjectType();
@@ -4591,7 +4591,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
45914591
bool MissingArgumentsFailure::diagnoseAsNote() {
45924592
auto *locator = getLocator();
45934593
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
4594-
auto *fn = resolveType(overload->openedType)->getAs<AnyFunctionType>();
4594+
auto *fn = resolveType(overload->adjustedOpenedType)->getAs<AnyFunctionType>();
45954595
auto loc = overload->choice.getDecl()->getLoc();
45964596

45974597
if (loc.isInvalid())
@@ -4915,7 +4915,7 @@ bool MissingArgumentsFailure::isMisplacedMissingArgument(
49154915
return false;
49164916

49174917
auto *fnType =
4918-
solution.simplifyType(overloadChoice->openedType)->getAs<FunctionType>();
4918+
solution.simplifyType(overloadChoice->adjustedOpenedType)->getAs<FunctionType>();
49194919
if (!(fnType && fnType->getNumParams() == 2))
49204920
return false;
49214921

lib/Sema/CSFix.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ bool AllowFunctionTypeMismatch::diagnoseForAmbiguity(
584584
auto *decl = overload->choice.getDecl();
585585
if (decl->getLoc().isValid()) {
586586
DE.diagnose(decl, diag::found_candidate_type,
587-
solution.simplifyType(overload->openedType));
587+
solution.simplifyType(overload->adjustedOpenedType));
588588
}
589589
}
590590

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,7 +2525,7 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType,
25252525
if (auto *typeVar = requirementType->getAs<TypeVariableType>()) {
25262526
unsigned choiceImpact = 0;
25272527
if (auto choice = cs.findSelectedOverloadFor(ODRE)) {
2528-
choice->openedType.visit([&](Type type) {
2528+
choice->adjustedOpenedType.visit([&](Type type) {
25292529
if (type->isEqual(typeVar))
25302530
++choiceImpact;
25312531
});
@@ -4350,7 +4350,7 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
43504350
if (!(overload && overload->choice.isDecl()))
43514351
return false;
43524352

4353-
auto *fnType = overload->openedType->getAs<FunctionType>();
4353+
auto *fnType = overload->adjustedOpenedType->getAs<FunctionType>();
43544354
if (!(fnType && fnType->getNumParams() == 2))
43554355
return false;
43564356

@@ -5306,7 +5306,7 @@ bool ConstraintSystem::repairFailures(
53065306
auto callee = getCalleeLocator(loc);
53075307
if (auto overload = findSelectedOverloadFor(callee)) {
53085308
auto fnType =
5309-
simplifyType(overload->openedType)->castTo<FunctionType>();
5309+
simplifyType(overload->adjustedOpenedType)->castTo<FunctionType>();
53105310
auto paramIdx = argToParamElt->getParamIdx();
53115311
auto paramType = fnType->getParams()[paramIdx].getParameterType();
53125312
if (auto paramFnType = paramType->getAs<FunctionType>()) {

0 commit comments

Comments
 (0)