Skip to content

Commit 2a0b11a

Browse files
committed
Sema: Collect property wrappers in PreparedOverload
1 parent be6cf92 commit 2a0b11a

File tree

6 files changed

+95
-26
lines changed

6 files changed

+95
-26
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,7 +3621,8 @@ class ConstraintSystem {
36213621

36223622
/// Log and record the application of the fix. Return true iff any
36233623
/// subsequent solution would be worse than the best known solution.
3624-
bool recordFix(ConstraintFix *fix, unsigned impact = 1);
3624+
bool recordFix(ConstraintFix *fix, unsigned impact = 1,
3625+
PreparedOverload *preparedOverload = nullptr);
36253626

36263627
void recordPotentialHole(TypeVariableType *typeVar);
36273628
void recordAnyTypeVarAsPotentialHole(Type type);
@@ -5333,13 +5334,20 @@ class ConstraintSystem {
53335334
/// Matches a wrapped or projected value parameter type to its backing
53345335
/// property wrapper type by applying the property wrapper.
53355336
TypeMatchResult applyPropertyWrapperToParameter(
5336-
Type wrapperType, Type paramType, ParamDecl *param, Identifier argLabel,
5337-
ConstraintKind matchKind, ConstraintLocator *locator,
5338-
ConstraintLocator *calleeLocator);
5337+
Type wrapperType,
5338+
Type paramType,
5339+
ParamDecl *param,
5340+
Identifier argLabel,
5341+
ConstraintKind matchKind,
5342+
ConstraintLocator *locator,
5343+
ConstraintLocator *calleeLocator,
5344+
PreparedOverload *preparedOverload = nullptr);
53395345

53405346
/// Used by applyPropertyWrapperToParameter() to update appliedPropertyWrappers
53415347
/// and record a change in the trail.
5342-
void applyPropertyWrapper(Expr *anchor, AppliedPropertyWrapper applied);
5348+
void applyPropertyWrapper(Expr *anchor,
5349+
AppliedPropertyWrapper applied,
5350+
PreparedOverload *preparedOverload = nullptr);
53435351

53445352
/// Undo the above change.
53455353
void removePropertyWrapper(Expr *anchor);

include/swift/Sema/PreparedOverload.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef SWIFT_SEMA_PREPAREDOVERLOAD_H
1313
#define SWIFT_SEMA_PREPAREDOVERLOAD_H
1414

15+
#include "swift/AST/PropertyWrappers.h"
1516
#include "llvm/ADT/PointerIntPair.h"
1617
#include "llvm/ADT/SmallVector.h"
1718

@@ -37,6 +38,8 @@ struct PreparedOverload {
3738
ExistentialArchetypeType *OpenedExistential = nullptr;
3839
SmallVector<std::pair<PackExpansionType *, TypeVariableType *>>
3940
OpenedPackExpansionTypes;
41+
SmallVector<AppliedPropertyWrapper, 2> PropertyWrappers;
42+
SmallVector<std::pair<ConstraintFix *, unsigned>, 2> Fixes;
4043

4144
void discharge(ConstraintSystem &cs, ConstraintLocatorBuilder locator) const;
4245
};

lib/Sema/CSGen.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/Sema/ConstraintGraph.h"
3333
#include "swift/Sema/ConstraintSystem.h"
3434
#include "swift/Sema/IDETypeChecking.h"
35+
#include "swift/Sema/PreparedOverload.h"
3536
#include "swift/Subsystems.h"
3637
#include "llvm/ADT/APInt.h"
3738
#include "llvm/ADT/SetVector.h"
@@ -5117,7 +5118,16 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
51175118
}
51185119

51195120
void ConstraintSystem::applyPropertyWrapper(
5120-
Expr *anchor, AppliedPropertyWrapper applied) {
5121+
Expr *anchor, AppliedPropertyWrapper applied,
5122+
PreparedOverload *preparedOverload) {
5123+
if (preparedOverload) {
5124+
ASSERT(PreparingOverload);
5125+
preparedOverload->PropertyWrappers.push_back(applied);
5126+
return;
5127+
}
5128+
5129+
ASSERT(!PreparingOverload);
5130+
51215131
appliedPropertyWrappers[anchor].push_back(applied);
51225132

51235133
if (solverState)
@@ -5138,9 +5148,14 @@ void ConstraintSystem::removePropertyWrapper(Expr *anchor) {
51385148

51395149
ConstraintSystem::TypeMatchResult
51405150
ConstraintSystem::applyPropertyWrapperToParameter(
5141-
Type wrapperType, Type paramType, ParamDecl *param, Identifier argLabel,
5142-
ConstraintKind matchKind, ConstraintLocator *locator,
5143-
ConstraintLocator *calleeLocator) {
5151+
Type wrapperType,
5152+
Type paramType,
5153+
ParamDecl *param,
5154+
Identifier argLabel,
5155+
ConstraintKind matchKind,
5156+
ConstraintLocator *locator,
5157+
ConstraintLocator *calleeLocator,
5158+
PreparedOverload *preparedOverload) {
51445159
Expr *anchor = getAsExpr(calleeLocator->getAnchor());
51455160

51465161
auto recordPropertyWrapperFix = [&](ConstraintFix *fix) -> TypeMatchResult {
@@ -5149,7 +5164,7 @@ ConstraintSystem::applyPropertyWrapperToParameter(
51495164

51505165
recordAnyTypeVarAsPotentialHole(paramType);
51515166

5152-
if (recordFix(fix))
5167+
if (recordFix(fix, /*impact=*/1, preparedOverload))
51535168
return getTypeMatchFailure(locator);
51545169

51555170
return getTypeMatchSuccess();
@@ -5176,21 +5191,33 @@ ConstraintSystem::applyPropertyWrapperToParameter(
51765191

51775192
if (argLabel.hasDollarPrefix()) {
51785193
Type projectionType = computeProjectedValueType(param, wrapperType);
5179-
addConstraint(matchKind, paramType, projectionType, locator);
5194+
addConstraint(matchKind, paramType, projectionType, locator,
5195+
/*isFavored=*/false,
5196+
preparedOverload);
51805197
if (param->hasImplicitPropertyWrapper()) {
51815198
auto wrappedValueType = getType(param->getPropertyWrapperWrappedValueVar());
5182-
addConstraint(ConstraintKind::PropertyWrapper, projectionType, wrappedValueType,
5183-
getConstraintLocator(param));
5199+
addConstraint(ConstraintKind::PropertyWrapper,
5200+
projectionType, wrappedValueType,
5201+
getConstraintLocator(param),
5202+
/*isFavored=*/false,
5203+
preparedOverload);
51845204
setType(param->getPropertyWrapperProjectionVar(), projectionType);
51855205
}
51865206

5187-
applyPropertyWrapper(anchor, { wrapperType, PropertyWrapperInitKind::ProjectedValue });
5207+
applyPropertyWrapper(anchor,
5208+
{ wrapperType, PropertyWrapperInitKind::ProjectedValue },
5209+
preparedOverload);
51885210
} else if (param->hasExternalPropertyWrapper()) {
51895211
Type wrappedValueType = computeWrappedValueType(param, wrapperType);
5190-
addConstraint(matchKind, paramType, wrappedValueType, locator);
5212+
addConstraint(matchKind, paramType, wrappedValueType,
5213+
locator,
5214+
/*isFavored=*/false,
5215+
preparedOverload);
51915216
setType(param->getPropertyWrapperWrappedValueVar(), wrappedValueType);
51925217

5193-
applyPropertyWrapper(anchor, { wrapperType, PropertyWrapperInitKind::WrappedValue });
5218+
applyPropertyWrapper(anchor,
5219+
{ wrapperType, PropertyWrapperInitKind::WrappedValue },
5220+
preparedOverload);
51945221
} else {
51955222
return getTypeMatchFailure(locator);
51965223
}

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15403,7 +15403,16 @@ static bool isAugmentingFix(ConstraintFix *fix) {
1540315403
}
1540415404
}
1540515405

15406-
bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
15406+
bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact,
15407+
PreparedOverload *preparedOverload) {
15408+
if (preparedOverload) {
15409+
ASSERT(PreparingOverload);
15410+
preparedOverload->Fixes.push_back({fix, impact});
15411+
return true;
15412+
}
15413+
15414+
ASSERT(!PreparingOverload);
15415+
1540715416
if (isDebugMode()) {
1540815417
auto &log = llvm::errs();
1540915418
log.indent(solverState ? solverState->getCurrentIndent() : 0)

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ void ConstraintSystem::removeConversionRestriction(
307307
}
308308

309309
void ConstraintSystem::addFix(ConstraintFix *fix) {
310+
ASSERT(!PreparingOverload);
311+
310312
bool inserted = Fixes.insert(fix);
311313
ASSERT(inserted);
312314

lib/Sema/TypeOfReference.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -804,9 +804,12 @@ unsigned constraints::getNumApplications(bool hasAppliedSelf,
804804
/// Replaces property wrapper types in the parameter list of the given function type
805805
/// with the wrapped-value or projected-value types (depending on argument label).
806806
static FunctionType *
807-
unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs, AbstractFunctionDecl *funcDecl,
808-
FunctionRefInfo functionRefInfo, FunctionType *functionType,
809-
ConstraintLocatorBuilder locator) {
807+
unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs,
808+
AbstractFunctionDecl *funcDecl,
809+
FunctionRefInfo functionRefInfo,
810+
FunctionType *functionType,
811+
ConstraintLocatorBuilder locator,
812+
PreparedOverload *preparedOverload) {
810813
// Only apply property wrappers to unapplied references to functions.
811814
if (!functionRefInfo.isUnapplied())
812815
return functionType;
@@ -842,14 +845,15 @@ unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs, AbstractFunctionDecl *
842845
}
843846

844847
auto *loc = cs.getConstraintLocator(locator);
845-
auto *wrappedType = cs.createTypeVariable(loc, 0);
848+
auto *wrappedType = cs.createTypeVariable(loc, 0, preparedOverload);
846849
auto paramType = paramTypes[i].getParameterType();
847850
auto paramLabel = paramTypes[i].getLabel();
848851
auto paramInternalLabel = paramTypes[i].getInternalLabel();
849852
adjustedParamTypes.push_back(AnyFunctionType::Param(
850853
wrappedType, paramLabel, ParameterTypeFlags(), paramInternalLabel));
851-
cs.applyPropertyWrapperToParameter(paramType, wrappedType, paramDecl, argLabel,
852-
ConstraintKind::Equal, loc, loc);
854+
cs.applyPropertyWrapperToParameter(
855+
paramType, wrappedType, paramDecl, argLabel, ConstraintKind::Equal,
856+
loc, loc, preparedOverload);
853857
}
854858

855859
return FunctionType::get(adjustedParamTypes, functionType->getResult(),
@@ -1049,7 +1053,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
10491053
->removeArgumentLabels(numLabelsToRemove);
10501054
openedType = unwrapPropertyWrapperParameterTypes(
10511055
*this, funcDecl, functionRefInfo, openedType->castTo<FunctionType>(),
1052-
locator);
1056+
locator, preparedOverload);
10531057

10541058
auto origOpenedType = openedType;
10551059
if (!isRequirementOrWitness(locator)) {
@@ -1821,8 +1825,9 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
18211825

18221826
// Strip off the 'self' parameter
18231827
auto *functionType = fullFunctionType->getResult()->getAs<FunctionType>();
1824-
functionType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefInfo,
1825-
functionType, locator);
1828+
functionType = unwrapPropertyWrapperParameterTypes(
1829+
*this, funcDecl, functionRefInfo, functionType,
1830+
locator, preparedOverload);
18261831
// FIXME: Verify ExtInfo state is correct, not working by accident.
18271832
FunctionType::ExtInfo info;
18281833

@@ -2494,18 +2499,33 @@ void PreparedOverload::discharge(ConstraintSystem &cs,
24942499
for (auto *tv : TypeVariables) {
24952500
cs.addTypeVariable(tv);
24962501
}
2502+
24972503
for (auto *c : Constraints) {
24982504
cs.addUnsolvedConstraint(c);
24992505
cs.activateConstraint(c);
25002506
}
2507+
25012508
cs.recordOpenedTypes(locator, Replacements);
2509+
25022510
if (OpenedExistential) {
25032511
cs.recordOpenedExistentialType(cs.getConstraintLocator(locator),
25042512
OpenedExistential);
25052513
}
2514+
25062515
for (auto pair : OpenedPackExpansionTypes) {
25072516
cs.recordOpenedPackExpansionType(pair.first, pair.second);
25082517
}
2518+
2519+
if (!PropertyWrappers.empty()) {
2520+
Expr *anchor = getAsExpr(cs.getConstraintLocator(locator)->getAnchor());
2521+
for (auto applied : PropertyWrappers) {
2522+
cs.applyPropertyWrapper(anchor, applied);
2523+
}
2524+
}
2525+
2526+
for (auto pair : Fixes) {
2527+
cs.recordFix(pair.first, pair.second);
2528+
}
25092529
}
25102530

25112531
void ConstraintSystem::resolveOverload(ConstraintLocator *locator,

0 commit comments

Comments
 (0)