Skip to content

Commit a8d896a

Browse files
committed
Sema: Don't reuse PreparedOverload from normal type checking in salvage()
We want to re-prepare our overloads, since now they will contain fixes.
1 parent 036db6f commit a8d896a

File tree

6 files changed

+50
-19
lines changed

6 files changed

+50
-19
lines changed

include/swift/Sema/Constraint.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -883,11 +883,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
883883
return Overload.Prepared;
884884
}
885885

886-
void setPreparedOverload(PreparedOverload *preparedOverload) {
887-
ASSERT(Kind == ConstraintKind::BindOverload);
888-
ASSERT(!Overload.Prepared);
889-
Overload.Prepared = preparedOverload;
890-
}
886+
void setPreparedOverload(PreparedOverload *preparedOverload);
891887

892888
FunctionType *getAppliedFunctionType() const {
893889
assert(Kind == ConstraintKind::ApplicableFunction);

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4876,7 +4876,8 @@ class ConstraintSystem {
48764876
/// Build and allocate a prepared overload in the solver arena.
48774877
PreparedOverload *prepareOverload(OverloadChoice choice,
48784878
DeclContext *useDC,
4879-
ConstraintLocator *locator);
4879+
ConstraintLocator *locator,
4880+
bool forDiagnostics);
48804881

48814882
/// Populate the prepared overload with all type variables and constraints
48824883
/// that are to be introduced into the constraint system when this choice

include/swift/Sema/PreparedOverload.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,21 @@ class PreparedOverload final :
160160
private:
161161
Type OpenedType;
162162
Type ThrownErrorType;
163-
size_t Count;
163+
unsigned Count : 31;
164+
165+
/// A prepared overload for diagnostics is different than one without,
166+
/// because of fixes and such.
167+
unsigned ForDiagnostics : 1;
164168

165169
size_t numTrailingObjects(OverloadToken<Change>) const {
166170
return Count;
167171
}
168172

169173
public:
170174
PreparedOverload(Type openedType, Type thrownErrorType,
171-
ArrayRef<Change> changes)
175+
ArrayRef<Change> changes, bool forDiagnostics)
172176
: OpenedType(openedType), ThrownErrorType(thrownErrorType),
173-
Count(changes.size()) {
177+
Count(changes.size()), ForDiagnostics(forDiagnostics) {
174178
std::uninitialized_copy(changes.begin(), changes.end(),
175179
getTrailingObjects());
176180
}
@@ -183,6 +187,10 @@ class PreparedOverload final :
183187
return ThrownErrorType;
184188
}
185189

190+
bool wasForDiagnostics() const {
191+
return ForDiagnostics;
192+
}
193+
186194
ArrayRef<Change> getChanges() const { return getTrailingObjects(Count); }
187195
};
188196

lib/Sema/CSSimplify.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16837,16 +16837,24 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1683716837

1683816838
// FIXME: Transitional hack.
1683916839
bool enablePreparedOverloads = getASTContext().TypeCheckerOpts.SolverEnablePreparedOverloads;
16840+
bool forDiagnostics = inSalvageMode();
1684016841

16842+
// Don't reuse prepared overloads from normal type checking in salvage(),
16843+
// since they will contain fixes and such.
1684116844
auto *preparedOverload = constraint.getPreparedOverload();
16842-
if (!preparedOverload) {
16843-
if (enablePreparedOverloads &&
16844-
constraint.getOverloadChoice().canBePrepared()) {
16845-
preparedOverload = prepareOverload(constraint.getOverloadChoice(),
16846-
constraint.getDeclContext(),
16847-
constraint.getLocator());
16848-
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
16849-
}
16845+
if (preparedOverload &&
16846+
preparedOverload->wasForDiagnostics() != forDiagnostics) {
16847+
preparedOverload = nullptr;
16848+
}
16849+
16850+
if (!preparedOverload &&
16851+
enablePreparedOverloads &&
16852+
constraint.getOverloadChoice().canBePrepared()) {
16853+
preparedOverload = prepareOverload(constraint.getOverloadChoice(),
16854+
constraint.getDeclContext(),
16855+
constraint.getLocator(),
16856+
forDiagnostics);
16857+
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
1685016858
}
1685116859

1685216860
resolveOverload(constraint.getOverloadChoice(),

lib/Sema/Constraint.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/Basic/Compiler.h"
2121
#include "swift/Sema/Constraint.h"
2222
#include "swift/Sema/ConstraintSystem.h"
23+
#include "swift/Sema/PreparedOverload.h"
2324
#include "llvm/Support/Compiler.h"
2425
#include "llvm/Support/raw_ostream.h"
2526
#include <algorithm>
@@ -1142,3 +1143,18 @@ void *Constraint::operator new(size_t bytes, ConstraintSystem& cs,
11421143
size_t alignment) {
11431144
return ::operator new (bytes, cs, alignment);
11441145
}
1146+
1147+
// FIXME: Perhaps we should store the Constraint -> PreparedOverload mapping
1148+
// in a SolverStep or something? Mutating Constraint feels wrong.
1149+
1150+
void Constraint::setPreparedOverload(PreparedOverload *preparedOverload) {
1151+
ASSERT(Kind == ConstraintKind::BindOverload);
1152+
1153+
// We can only set a prepared overload at most once in normal
1154+
// type checking, and then once in salvage.
1155+
ASSERT(!Overload.Prepared ||
1156+
(!Overload.Prepared->wasForDiagnostics() &&
1157+
preparedOverload->wasForDiagnostics()));
1158+
1159+
Overload.Prepared = preparedOverload;
1160+
}

lib/Sema/TypeOfReference.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,8 @@ ConstraintSystem::prepareOverloadImpl(OverloadChoice choice,
28872887

28882888
PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
28892889
DeclContext *useDC,
2890-
ConstraintLocator *locator) {
2890+
ConstraintLocator *locator,
2891+
bool forDiagnostics) {
28912892
ASSERT(!PreparingOverload);
28922893
PreparingOverload = true;
28932894

@@ -2903,7 +2904,8 @@ PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
29032904
auto size = PreparedOverload::totalSizeToAlloc<PreparedOverload::Change>(count);
29042905
auto mem = Allocator.Allocate(size, alignof(PreparedOverload));
29052906

2906-
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes);
2907+
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes,
2908+
forDiagnostics);
29072909
}
29082910

29092911
void ConstraintSystem::resolveOverload(OverloadChoice choice, DeclContext *useDC,

0 commit comments

Comments
 (0)