Skip to content

Commit 248b72b

Browse files
committed
Track the pre-adjusted "reference" type for declaration reference.
1 parent 1063e81 commit 248b72b

9 files changed

+238
-189
lines changed

include/swift/Sema/ConstraintSystem.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,12 @@ struct SelectedOverload {
665665
/// The opened type produced by referring to this overload.
666666
const Type openedType;
667667

668+
/// The opened type produced by referring to this overload, adjusted for
669+
/// `@preconcurrency` or other contextual type-altering attributes.
670+
const Type adjustedOpenedType;
671+
668672
/// The type that this overload binds. Note that this may differ from
669-
/// openedType, for example it will include any IUO unwrapping that has taken
673+
/// adjustedOpenedType, for example it will include any IUO unwrapping that has taken
670674
/// place.
671675
const Type boundType;
672676
};
@@ -2533,10 +2537,15 @@ struct DeclReferenceType {
25332537
/// operation.
25342538
Type adjustedOpenedType;
25352539

2540+
/// The type of the reference, based on the original opened type. This is the
2541+
/// type that the expression used to form the declaration reference would
2542+
/// have if no adjustments had been applied.
2543+
Type referenceType;
2544+
25362545
/// The type of the reference, which is the adjusted opened type after
25372546
/// (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;
2547+
/// expression used to form the declaration reference.
2548+
Type adjustedReferenceType;
25402549
};
25412550

25422551
/// Describes a system of constraints on type variables, the
@@ -4554,6 +4563,14 @@ class ConstraintSystem {
45544563
return Type();
45554564
});
45564565

4566+
/// Given the opened type and a pile of information about a member reference,
4567+
/// determine the reference type of the member reference.
4568+
Type getMemberReferenceTypeFromOpenedType(
4569+
Type &openedType, Type baseObjTy, ValueDecl *value, DeclContext *outerDC,
4570+
ConstraintLocator *locator, bool hasAppliedSelf,
4571+
bool isStaticMemberRefOnProtocol, bool isDynamicResult,
4572+
OpenedTypeMap &replacements);
4573+
45574574
/// Retrieve the type of a reference to the given value declaration,
45584575
/// as a member with a base of the given type.
45594576
///

lib/IDE/ArgumentCompletion.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ SelectedOverloadInfo getSelectedOverloadInfo(const Solution &S,
116116

117117
Result.FuncD = SelectedOverload->choice.getDeclOrNull();
118118
Result.FuncTy =
119-
S.simplifyTypeForCodeCompletion(SelectedOverload->openedType);
119+
S.simplifyTypeForCodeCompletion(SelectedOverload->adjustedOpenedType);
120120

121121
// For completion as the arg in a call to the implicit [keypath: _]
122122
// subscript the solver can't know what kind of keypath is expected without
@@ -141,7 +141,7 @@ SelectedOverloadInfo getSelectedOverloadInfo(const Solution &S,
141141
break;
142142
}
143143
case OverloadChoiceKind::KeyPathDynamicMemberLookup: {
144-
auto *fnType = SelectedOverload->openedType->castTo<FunctionType>();
144+
auto *fnType = SelectedOverload->adjustedOpenedType->castTo<FunctionType>();
145145
assert(fnType->getParams().size() == 1 &&
146146
"subscript always has one argument");
147147
// Parameter type is KeyPath<T, U> where `T` is a root type

lib/Sema/CSApply.cpp

+22-17
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());
@@ -7664,7 +7669,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
76647669
cs.getConstraintLocator(applyFunctionLoc))) {
76657670
auto *method = dyn_cast<FuncDecl>(selected->choice.getDecl());
76667671
auto methodType =
7667-
simplifyType(selected->openedType)->getAs<AnyFunctionType>();
7672+
simplifyType(selected->adjustedOpenedType)->getAs<AnyFunctionType>();
76687673
if (method && methodType) {
76697674
// Handle a call to a @dynamicCallable method.
76707675
if (isValidDynamicCallableMethod(method, methodType))

lib/Sema/CSDiagnostics.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
13091309
// only a '?' fixit) even though the constraint system didn't need to add any
13101310
// additional optionality.
13111311
auto overload = getOverloadChoiceIfAvailable(locator);
1312-
if (overload && overload->openedType->getOptionalObjectType())
1312+
if (overload && overload->adjustedOpenedType->getOptionalObjectType())
13131313
resultIsOptional = true;
13141314

13151315
auto unwrappedBaseType = baseType->getOptionalObjectType();
@@ -4617,7 +4617,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
46174617
bool MissingArgumentsFailure::diagnoseAsNote() {
46184618
auto *locator = getLocator();
46194619
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
4620-
auto *fn = resolveType(overload->openedType)->getAs<AnyFunctionType>();
4620+
auto *fn = resolveType(overload->adjustedOpenedType)->getAs<AnyFunctionType>();
46214621
auto loc = overload->choice.getDecl()->getLoc();
46224622

46234623
if (loc.isInvalid())
@@ -4941,7 +4941,7 @@ bool MissingArgumentsFailure::isMisplacedMissingArgument(
49414941
return false;
49424942

49434943
auto *fnType =
4944-
solution.simplifyType(overloadChoice->openedType)->getAs<FunctionType>();
4944+
solution.simplifyType(overloadChoice->adjustedOpenedType)->getAs<FunctionType>();
49454945
if (!(fnType && fnType->getNumParams() == 2))
49464946
return false;
49474947

lib/Sema/CSFix.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ bool AllowFunctionTypeMismatch::diagnoseForAmbiguity(
608608
auto *decl = overload->choice.getDecl();
609609
if (decl->getLoc().isValid()) {
610610
DE.diagnose(decl, diag::found_candidate_type,
611-
solution.simplifyType(overload->openedType));
611+
solution.simplifyType(overload->adjustedOpenedType));
612612
}
613613
}
614614

lib/Sema/CSSimplify.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -2523,7 +2523,7 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType,
25232523
if (auto *typeVar = requirementType->getAs<TypeVariableType>()) {
25242524
unsigned choiceImpact = 0;
25252525
if (auto choice = cs.findSelectedOverloadFor(ODRE)) {
2526-
choice->openedType.visit([&](Type type) {
2526+
choice->adjustedOpenedType.visit([&](Type type) {
25272527
if (type->isEqual(typeVar))
25282528
++choiceImpact;
25292529
});
@@ -4323,7 +4323,7 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
43234323
if (!(overload && overload->choice.isDecl()))
43244324
return false;
43254325

4326-
auto *fnType = overload->openedType->getAs<FunctionType>();
4326+
auto *fnType = overload->adjustedOpenedType->getAs<FunctionType>();
43274327
if (!(fnType && fnType->getNumParams() == 2))
43284328
return false;
43294329

@@ -5279,7 +5279,7 @@ bool ConstraintSystem::repairFailures(
52795279
auto callee = getCalleeLocator(loc);
52805280
if (auto overload = findSelectedOverloadFor(callee)) {
52815281
auto fnType =
5282-
simplifyType(overload->openedType)->castTo<FunctionType>();
5282+
simplifyType(overload->adjustedOpenedType)->castTo<FunctionType>();
52835283
auto paramIdx = argToParamElt->getParamIdx();
52845284
auto paramType = fnType->getParams()[paramIdx].getParameterType();
52855285
if (auto paramFnType = paramType->getAs<FunctionType>()) {

0 commit comments

Comments
 (0)