Skip to content

Commit 5f897a8

Browse files
authored
Merge pull request #84821 from slavapestov/prepared-diagnostics
Small fixes for diagnostics with prepared overloads enabled
2 parents 451dcd6 + 8600cdc commit 5f897a8

File tree

8 files changed

+73
-49
lines changed

8 files changed

+73
-49
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: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,9 +2131,7 @@ class SyntacticElementTargetRewriter {
21312131

21322132
enum class ConstraintSystemPhase {
21332133
ConstraintGeneration,
2134-
Solving,
2135-
Diagnostics,
2136-
Finalization
2134+
Solving
21372135
};
21382136

21392137
/// Retrieve the closure type from the constraint system.
@@ -2693,18 +2691,7 @@ class ConstraintSystem {
26932691
case ConstraintSystemPhase::Solving:
26942692
// We can come back to constraint generation phase while
26952693
// processing result builder body.
2696-
assert(newPhase == ConstraintSystemPhase::ConstraintGeneration ||
2697-
newPhase == ConstraintSystemPhase::Diagnostics ||
2698-
newPhase == ConstraintSystemPhase::Finalization);
2699-
break;
2700-
2701-
case ConstraintSystemPhase::Diagnostics:
2702-
assert(newPhase == ConstraintSystemPhase::Solving ||
2703-
newPhase == ConstraintSystemPhase::Finalization);
2704-
break;
2705-
2706-
case ConstraintSystemPhase::Finalization:
2707-
assert(newPhase == ConstraintSystemPhase::Diagnostics);
2694+
assert(newPhase == ConstraintSystemPhase::ConstraintGeneration);
27082695
break;
27092696
}
27102697
#endif
@@ -4876,7 +4863,8 @@ class ConstraintSystem {
48764863
/// Build and allocate a prepared overload in the solver arena.
48774864
PreparedOverload *prepareOverload(OverloadChoice choice,
48784865
DeclContext *useDC,
4879-
ConstraintLocator *locator);
4866+
ConstraintLocator *locator,
4867+
bool forDiagnostics);
48804868

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

include/swift/Sema/PreparedOverload.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ struct PreparedOverloadChange {
104104
/// For ChangeKind::AddedConstraint.
105105
Constraint *TheConstraint;
106106

107+
/// For ChangeKind::AddedBindConstraint.
107108
struct {
108109
TypeBase *FirstType;
109-
TypeBase * SecondType;
110+
TypeBase *SecondType;
110111
} Bind;
111112

112113
/// For ChangeKind::OpenedTypes.
@@ -159,17 +160,21 @@ class PreparedOverload final :
159160
private:
160161
Type OpenedType;
161162
Type ThrownErrorType;
162-
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;
163168

164169
size_t numTrailingObjects(OverloadToken<Change>) const {
165170
return Count;
166171
}
167172

168173
public:
169174
PreparedOverload(Type openedType, Type thrownErrorType,
170-
ArrayRef<Change> changes)
175+
ArrayRef<Change> changes, bool forDiagnostics)
171176
: OpenedType(openedType), ThrownErrorType(thrownErrorType),
172-
Count(changes.size()) {
177+
Count(changes.size()), ForDiagnostics(forDiagnostics) {
173178
std::uninitialized_copy(changes.begin(), changes.end(),
174179
getTrailingObjects());
175180
}
@@ -182,11 +187,19 @@ class PreparedOverload final :
182187
return ThrownErrorType;
183188
}
184189

190+
bool wasForDiagnostics() const {
191+
return ForDiagnostics;
192+
}
193+
185194
ArrayRef<Change> getChanges() const { return getTrailingObjects(Count); }
186195
};
187196

188197
struct PreparedOverloadBuilder {
189198
SmallVector<PreparedOverload::Change, 8> Changes;
199+
ConstraintLocator *Locator;
200+
201+
PreparedOverloadBuilder(ConstraintLocator *locator)
202+
: Locator(locator) {}
190203

191204
void addedTypeVariable(TypeVariableType *typeVar) {
192205
PreparedOverload::Change change;

lib/Sema/CSSimplify.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16529,14 +16529,22 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
1652916529
PreparedOverloadBuilder *preparedOverload) {
1653016530
if (preparedOverload) {
1653116531
ASSERT(PreparingOverload);
16532-
if (kind == ConstraintKind::Bind) {
16532+
16533+
auto *locatorPtr = getConstraintLocator(locator);
16534+
16535+
// Fast path to save on memory usage.
16536+
if (kind == ConstraintKind::Bind &&
16537+
locatorPtr == preparedOverload->Locator) {
1653316538
ASSERT(!isFavored);
1653416539
preparedOverload->addedBindConstraint(first, second);
1653516540
return;
1653616541
}
16537-
auto c = Constraint::create(*this, kind, first, second,
16538-
getConstraintLocator(locator));
16539-
if (isFavored) c->setFavored();
16542+
16543+
auto c = Constraint::create(*this, kind, first, second, locatorPtr);
16544+
16545+
if (isFavored)
16546+
c->setFavored();
16547+
1654016548
preparedOverload->addedConstraint(c);
1654116549
return;
1654216550
}
@@ -16829,16 +16837,24 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1682916837

1683016838
// FIXME: Transitional hack.
1683116839
bool enablePreparedOverloads = getASTContext().TypeCheckerOpts.SolverEnablePreparedOverloads;
16840+
bool forDiagnostics = inSalvageMode();
1683216841

16842+
// Don't reuse prepared overloads from normal type checking in salvage(),
16843+
// since they will contain fixes and such.
1683316844
auto *preparedOverload = constraint.getPreparedOverload();
16834-
if (!preparedOverload) {
16835-
if (enablePreparedOverloads &&
16836-
constraint.getOverloadChoice().canBePrepared()) {
16837-
preparedOverload = prepareOverload(constraint.getOverloadChoice(),
16838-
constraint.getDeclContext(),
16839-
constraint.getLocator());
16840-
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
16841-
}
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);
1684216858
}
1684316859

1684416860
resolveOverload(constraint.getOverloadChoice(),

lib/Sema/CSSolver.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,8 +1579,6 @@ void ConstraintSystem::solveImpl(SmallVectorImpl<Solution> &solutions) {
15791579

15801580
setPhase(ConstraintSystemPhase::Solving);
15811581

1582-
SWIFT_DEFER { setPhase(ConstraintSystemPhase::Finalization); };
1583-
15841582
// If constraint system failed while trying to
15851583
// genenerate constraints, let's stop right here.
15861584
if (failedConstraint)

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/ConstraintSystem.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,8 +2098,6 @@ SolutionResult ConstraintSystem::salvage() {
20982098
llvm::errs() << "---Attempting to salvage and emit diagnostics---\n";
20992099
}
21002100

2101-
setPhase(ConstraintSystemPhase::Diagnostics);
2102-
21032101
// Attempt to solve again, capturing all states that come from our attempts to
21042102
// select overloads or bind type variables.
21052103
//
@@ -4797,10 +4795,6 @@ void SyntacticElementTargetKey::dump(raw_ostream &OS) const {
47974795
/// This is guaranteed to always emit an error message.
47984796
///
47994797
void ConstraintSystem::diagnoseFailureFor(SyntacticElementTarget target) {
4800-
setPhase(ConstraintSystemPhase::Diagnostics);
4801-
4802-
SWIFT_DEFER { setPhase(ConstraintSystemPhase::Finalization); };
4803-
48044798
auto &DE = getASTContext().Diags;
48054799

48064800
// If constraint system is in invalid state always produce

lib/Sema/TypeOfReference.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2811,7 +2811,8 @@ void ConstraintSystem::replayChanges(
28112811
addConstraint(ConstraintKind::Bind,
28122812
change.Bind.FirstType,
28132813
change.Bind.SecondType,
2814-
locator, /*isFavored=*/false);
2814+
locator,
2815+
/*isFavored=*/false);
28152816
break;
28162817

28172818
case PreparedOverload::Change::OpenedTypes: {
@@ -2886,11 +2887,12 @@ ConstraintSystem::prepareOverloadImpl(OverloadChoice choice,
28862887

28872888
PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
28882889
DeclContext *useDC,
2889-
ConstraintLocator *locator) {
2890+
ConstraintLocator *locator,
2891+
bool forDiagnostics) {
28902892
ASSERT(!PreparingOverload);
28912893
PreparingOverload = true;
28922894

2893-
PreparedOverloadBuilder builder;
2895+
PreparedOverloadBuilder builder(locator);
28942896
Type openedType;
28952897
Type thrownErrorType;
28962898
std::tie(openedType, thrownErrorType) = prepareOverloadImpl(
@@ -2902,7 +2904,8 @@ PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
29022904
auto size = PreparedOverload::totalSizeToAlloc<PreparedOverload::Change>(count);
29032905
auto mem = Allocator.Allocate(size, alignof(PreparedOverload));
29042906

2905-
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes);
2907+
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes,
2908+
forDiagnostics);
29062909
}
29072910

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

0 commit comments

Comments
 (0)