Skip to content

Commit 355786c

Browse files
authored
Merge pull request #83015 from slavapestov/prepared-overloads-part-3
Prepared overloads, part 3
2 parents 3eddbbb + b39d3ae commit 355786c

File tree

6 files changed

+63
-25
lines changed

6 files changed

+63
-25
lines changed

include/swift/Sema/Constraint.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
495495

496496
/// Construct a new overload-binding constraint, which might have a fix.
497497
Constraint(Type type, OverloadChoice choice,
498-
PreparedOverload *preparedOverload,
499498
DeclContext *useDC,
500499
ConstraintFix *fix, ConstraintLocator *locator,
501500
SmallPtrSetImpl<TypeVariableType *> &typeVars);
@@ -884,6 +883,12 @@ class Constraint final : public llvm::ilist_node<Constraint>,
884883
return Overload.Prepared;
885884
}
886885

886+
void setPreparedOverload(PreparedOverload *preparedOverload) {
887+
ASSERT(Kind == ConstraintKind::BindOverload);
888+
ASSERT(!Overload.Prepared);
889+
Overload.Prepared = preparedOverload;
890+
}
891+
887892
FunctionType *getAppliedFunctionType() const {
888893
assert(Kind == ConstraintKind::ApplicableFunction);
889894
return Apply.AppliedFn;

include/swift/Sema/PreparedOverload.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ struct PreparedOverloadChange {
7171
/// A generic requirement was opened to a constraint.
7272
AddedConstraint,
7373

74+
/// Special case of a Bind constraint.
75+
AddedBindConstraint,
76+
7477
/// A mapping of generic parameter types to type variables
7578
/// was recorded.
7679
OpenedTypes,
@@ -98,6 +101,11 @@ struct PreparedOverloadChange {
98101
/// For ChangeKind::AddedConstraint.
99102
Constraint *TheConstraint;
100103

104+
struct {
105+
TypeBase *FirstType;
106+
TypeBase * SecondType;
107+
} Bind;
108+
101109
/// For ChangeKind::OpenedTypes.
102110
struct {
103111
const OpenedType *Data;
@@ -192,6 +200,14 @@ struct PreparedOverloadBuilder {
192200
Changes.push_back(change);
193201
}
194202

203+
void addedBindConstraint(Type firstType, Type secondType) {
204+
PreparedOverload::Change change;
205+
change.Kind = PreparedOverload::Change::AddedBindConstraint;
206+
change.Bind.FirstType = firstType.getPointer();
207+
change.Bind.SecondType = secondType.getPointer();
208+
Changes.push_back(change);
209+
}
210+
195211
void openedTypes(ArrayRef<OpenedType> replacements) {
196212
PreparedOverload::Change change;
197213
change.Kind = PreparedOverload::Change::OpenedTypes;

lib/Sema/CSSimplify.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16365,6 +16365,11 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
1636516365
PreparedOverloadBuilder *preparedOverload) {
1636616366
if (preparedOverload) {
1636716367
ASSERT(PreparingOverload);
16368+
if (kind == ConstraintKind::Bind) {
16369+
ASSERT(!isFavored);
16370+
preparedOverload->addedBindConstraint(first, second);
16371+
return;
16372+
}
1636816373
auto c = Constraint::create(*this, kind, first, second,
1636916374
getConstraintLocator(locator));
1637016375
if (isFavored) c->setFavored();
@@ -16648,7 +16653,7 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1664816653
constraint.getFirstType(), constraint.getSecondType(),
1664916654
constraint.getThirdType(), std::nullopt, constraint.getLocator());
1665016655

16651-
case ConstraintKind::BindOverload:
16656+
case ConstraintKind::BindOverload: {
1665216657
if (auto *fix = constraint.getFix()) {
1665316658
// TODO(diagnostics): Impact should be associated with a fix unless
1665416659
// it's a contextual problem, then only solver can decide what the impact
@@ -16659,11 +16664,26 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1665916664
return SolutionKind::Error;
1666016665
}
1666116666

16667+
// FIXME: Transitional hack.
16668+
bool enablePreparedOverloads = false;
16669+
16670+
auto *preparedOverload = constraint.getPreparedOverload();
16671+
if (!preparedOverload) {
16672+
if (enablePreparedOverloads &&
16673+
constraint.getOverloadChoice().canBePrepared()) {
16674+
preparedOverload = prepareOverload(constraint.getLocator(),
16675+
constraint.getOverloadChoice(),
16676+
constraint.getDeclContext());
16677+
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
16678+
}
16679+
}
16680+
1666216681
resolveOverload(constraint.getLocator(), constraint.getFirstType(),
1666316682
constraint.getOverloadChoice(),
1666416683
constraint.getDeclContext(),
16665-
constraint.getPreparedOverload());
16684+
preparedOverload);
1666616685
return SolutionKind::Solved;
16686+
}
1666716687

1666816688
case ConstraintKind::SubclassOf:
1666916689
return simplifySubclassOfConstraint(constraint.getFirstType(),

lib/Sema/Constraint.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,14 @@ Constraint::Constraint(ConstraintKind kind, Type first, Type second,
246246
}
247247

248248
Constraint::Constraint(Type type, OverloadChoice choice,
249-
PreparedOverload *preparedOverload,
250249
DeclContext *useDC,
251250
ConstraintFix *fix, ConstraintLocator *locator,
252251
SmallPtrSetImpl<TypeVariableType *> &typeVars)
253252
: Kind(ConstraintKind::BindOverload), NumTypeVariables(typeVars.size()),
254253
HasFix(fix != nullptr), HasDeclContext(true), HasRestriction(false),
255254
IsActive(false), IsDisabled(bool(fix)), IsDisabledForPerformance(false),
256255
RememberChoice(false), IsFavored(false), IsIsolated(false),
257-
Overload{type, preparedOverload}, Locator(locator) {
256+
Overload{type, /*preparedOverload=*/nullptr}, Locator(locator) {
258257
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
259258
if (fix)
260259
*getTrailingObjects<ConstraintFix *>() = fix;
@@ -899,18 +898,6 @@ Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type,
899898
DeclContext *useDC,
900899
ConstraintFix *fix,
901900
ConstraintLocator *locator) {
902-
// FIXME: Transitional hack.
903-
bool enablePreparedOverloads = false;
904-
905-
PreparedOverload *preparedOverload = nullptr;
906-
907-
// Prepare the overload.
908-
if (enablePreparedOverloads) {
909-
if (choice.canBePrepared()) {
910-
preparedOverload = cs.prepareOverload(locator, choice, useDC);
911-
}
912-
}
913-
914901
// Collect type variables.
915902
SmallPtrSet<TypeVariableType *, 4> typeVars;
916903
if (type->hasTypeVariable())
@@ -926,7 +913,7 @@ Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type,
926913
typeVars.size(), fix ? 1 : 0, /*hasDeclContext=*/1,
927914
/*hasContextualTypeInfo=*/0, /*hasOverloadChoice=*/1);
928915
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
929-
return new (mem) Constraint(type, choice, preparedOverload, useDC,
916+
return new (mem) Constraint(type, choice, useDC,
930917
fix, locator, typeVars);
931918
}
932919

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@ std::optional<Type> ConstraintSystem::isSetType(Type type) {
10851085

10861086
Type ConstraintSystem::getFixedTypeRecursive(Type type, TypeMatchOptions &flags,
10871087
bool wantRValue) {
1088+
ASSERT(!PreparingOverload);
10881089

10891090
if (wantRValue)
10901091
type = type->getRValueType();
@@ -1753,6 +1754,8 @@ Type ConstraintSystem::simplifyTypeImpl(Type type,
17531754
}
17541755

17551756
Type ConstraintSystem::simplifyType(Type type) {
1757+
ASSERT(!PreparingOverload);
1758+
17561759
if (!type->hasTypeVariable())
17571760
return type;
17581761

lib/Sema/TypeOfReference.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,19 +1594,19 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
15941594
ASSERT(!!preparedOverload == PreparingOverload);
15951595

15961596
// Figure out the instance type used for the base.
1597-
Type resolvedBaseTy = getFixedTypeRecursive(baseTy, /*wantRValue=*/true);
1597+
Type baseRValueTy = baseTy->getRValueType();
15981598

15991599
// If the base is a module type, just use the type of the decl.
1600-
if (resolvedBaseTy->is<ModuleType>()) {
1600+
if (baseRValueTy->is<ModuleType>()) {
16011601
return getTypeOfReference(value, functionRefInfo, locator, useDC,
16021602
preparedOverload);
16031603
}
16041604

16051605
// Check to see if the self parameter is applied, in which case we'll want to
16061606
// strip it off later.
1607-
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(resolvedBaseTy, value);
1607+
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseRValueTy, value);
16081608

1609-
auto baseObjTy = resolvedBaseTy->getMetatypeInstanceType();
1609+
auto baseObjTy = baseRValueTy->getMetatypeInstanceType();
16101610
FunctionType::Param baseObjParam(baseObjTy);
16111611

16121612
// Indicates whether this is a valid reference to a static member on a
@@ -1617,7 +1617,7 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
16171617
bool isStaticMemberRefOnProtocol = false;
16181618
if (baseObjTy->isExistentialType() && value->isStatic() &&
16191619
locator->isLastElement<LocatorPathElt::UnresolvedMember>()) {
1620-
assert(resolvedBaseTy->is<MetatypeType>() &&
1620+
assert(baseRValueTy->is<MetatypeType>() &&
16211621
"Assumed base of unresolved member access must be a metatype");
16221622
isStaticMemberRefOnProtocol = true;
16231623
}
@@ -1846,12 +1846,12 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
18461846
} else if (isa<AbstractFunctionDecl>(value) || isa<EnumElementDecl>(value)) {
18471847
unsigned numApplies = getNumApplications(hasAppliedSelf, functionRefInfo);
18481848
openedType = adjustFunctionTypeForConcurrency(
1849-
origOpenedType->castTo<FunctionType>(), resolvedBaseTy, value, useDC,
1849+
origOpenedType->castTo<FunctionType>(), baseRValueTy, value, useDC,
18501850
numApplies, isMainDispatchQueueMember(locator), replacements, locator,
18511851
preparedOverload);
18521852
} else if (auto subscript = dyn_cast<SubscriptDecl>(value)) {
18531853
openedType = adjustFunctionTypeForConcurrency(
1854-
origOpenedType->castTo<FunctionType>(), resolvedBaseTy, subscript, useDC,
1854+
origOpenedType->castTo<FunctionType>(), baseRValueTy, subscript, useDC,
18551855
/*numApplies=*/2, /*isMainDispatchQueue=*/false, replacements, locator,
18561856
preparedOverload);
18571857
} else if (auto var = dyn_cast<VarDecl>(value)) {
@@ -2510,6 +2510,13 @@ void ConstraintSystem::replayChanges(
25102510
simplifyDisjunctionChoice(change.TheConstraint);
25112511
break;
25122512

2513+
case PreparedOverload::Change::AddedBindConstraint:
2514+
addConstraint(ConstraintKind::Bind,
2515+
change.Bind.FirstType,
2516+
change.Bind.SecondType,
2517+
locator, /*isFavored=*/false);
2518+
break;
2519+
25132520
case PreparedOverload::Change::OpenedTypes: {
25142521
ArrayRef<OpenedType> replacements(
25152522
change.Replacements.Data,

0 commit comments

Comments
 (0)