mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Don't reuse PreparedOverload from normal type checking in salvage()
We want to re-prepare our overloads, since now they will contain fixes.
This commit is contained in:
@@ -883,11 +883,7 @@ public:
|
|||||||
return Overload.Prepared;
|
return Overload.Prepared;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPreparedOverload(PreparedOverload *preparedOverload) {
|
void setPreparedOverload(PreparedOverload *preparedOverload);
|
||||||
ASSERT(Kind == ConstraintKind::BindOverload);
|
|
||||||
ASSERT(!Overload.Prepared);
|
|
||||||
Overload.Prepared = preparedOverload;
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionType *getAppliedFunctionType() const {
|
FunctionType *getAppliedFunctionType() const {
|
||||||
assert(Kind == ConstraintKind::ApplicableFunction);
|
assert(Kind == ConstraintKind::ApplicableFunction);
|
||||||
|
|||||||
@@ -4876,7 +4876,8 @@ public:
|
|||||||
/// Build and allocate a prepared overload in the solver arena.
|
/// Build and allocate a prepared overload in the solver arena.
|
||||||
PreparedOverload *prepareOverload(OverloadChoice choice,
|
PreparedOverload *prepareOverload(OverloadChoice choice,
|
||||||
DeclContext *useDC,
|
DeclContext *useDC,
|
||||||
ConstraintLocator *locator);
|
ConstraintLocator *locator,
|
||||||
|
bool forDiagnostics);
|
||||||
|
|
||||||
/// Populate the prepared overload with all type variables and constraints
|
/// Populate the prepared overload with all type variables and constraints
|
||||||
/// that are to be introduced into the constraint system when this choice
|
/// that are to be introduced into the constraint system when this choice
|
||||||
|
|||||||
@@ -160,7 +160,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
Type OpenedType;
|
Type OpenedType;
|
||||||
Type ThrownErrorType;
|
Type ThrownErrorType;
|
||||||
size_t Count;
|
unsigned Count : 31;
|
||||||
|
|
||||||
|
/// A prepared overload for diagnostics is different than one without,
|
||||||
|
/// because of fixes and such.
|
||||||
|
unsigned ForDiagnostics : 1;
|
||||||
|
|
||||||
size_t numTrailingObjects(OverloadToken<Change>) const {
|
size_t numTrailingObjects(OverloadToken<Change>) const {
|
||||||
return Count;
|
return Count;
|
||||||
@@ -168,9 +172,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
PreparedOverload(Type openedType, Type thrownErrorType,
|
PreparedOverload(Type openedType, Type thrownErrorType,
|
||||||
ArrayRef<Change> changes)
|
ArrayRef<Change> changes, bool forDiagnostics)
|
||||||
: OpenedType(openedType), ThrownErrorType(thrownErrorType),
|
: OpenedType(openedType), ThrownErrorType(thrownErrorType),
|
||||||
Count(changes.size()) {
|
Count(changes.size()), ForDiagnostics(forDiagnostics) {
|
||||||
std::uninitialized_copy(changes.begin(), changes.end(),
|
std::uninitialized_copy(changes.begin(), changes.end(),
|
||||||
getTrailingObjects());
|
getTrailingObjects());
|
||||||
}
|
}
|
||||||
@@ -183,6 +187,10 @@ public:
|
|||||||
return ThrownErrorType;
|
return ThrownErrorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wasForDiagnostics() const {
|
||||||
|
return ForDiagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayRef<Change> getChanges() const { return getTrailingObjects(Count); }
|
ArrayRef<Change> getChanges() const { return getTrailingObjects(Count); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16837,17 +16837,25 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
|
|||||||
|
|
||||||
// FIXME: Transitional hack.
|
// FIXME: Transitional hack.
|
||||||
bool enablePreparedOverloads = getASTContext().TypeCheckerOpts.SolverEnablePreparedOverloads;
|
bool enablePreparedOverloads = getASTContext().TypeCheckerOpts.SolverEnablePreparedOverloads;
|
||||||
|
bool forDiagnostics = inSalvageMode();
|
||||||
|
|
||||||
|
// Don't reuse prepared overloads from normal type checking in salvage(),
|
||||||
|
// since they will contain fixes and such.
|
||||||
auto *preparedOverload = constraint.getPreparedOverload();
|
auto *preparedOverload = constraint.getPreparedOverload();
|
||||||
if (!preparedOverload) {
|
if (preparedOverload &&
|
||||||
if (enablePreparedOverloads &&
|
preparedOverload->wasForDiagnostics() != forDiagnostics) {
|
||||||
|
preparedOverload = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preparedOverload &&
|
||||||
|
enablePreparedOverloads &&
|
||||||
constraint.getOverloadChoice().canBePrepared()) {
|
constraint.getOverloadChoice().canBePrepared()) {
|
||||||
preparedOverload = prepareOverload(constraint.getOverloadChoice(),
|
preparedOverload = prepareOverload(constraint.getOverloadChoice(),
|
||||||
constraint.getDeclContext(),
|
constraint.getDeclContext(),
|
||||||
constraint.getLocator());
|
constraint.getLocator(),
|
||||||
|
forDiagnostics);
|
||||||
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
|
const_cast<Constraint &>(constraint).setPreparedOverload(preparedOverload);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
resolveOverload(constraint.getOverloadChoice(),
|
resolveOverload(constraint.getOverloadChoice(),
|
||||||
constraint.getDeclContext(),
|
constraint.getDeclContext(),
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "swift/Basic/Compiler.h"
|
#include "swift/Basic/Compiler.h"
|
||||||
#include "swift/Sema/Constraint.h"
|
#include "swift/Sema/Constraint.h"
|
||||||
#include "swift/Sema/ConstraintSystem.h"
|
#include "swift/Sema/ConstraintSystem.h"
|
||||||
|
#include "swift/Sema/PreparedOverload.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -1142,3 +1143,18 @@ void *Constraint::operator new(size_t bytes, ConstraintSystem& cs,
|
|||||||
size_t alignment) {
|
size_t alignment) {
|
||||||
return ::operator new (bytes, cs, alignment);
|
return ::operator new (bytes, cs, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Perhaps we should store the Constraint -> PreparedOverload mapping
|
||||||
|
// in a SolverStep or something? Mutating Constraint feels wrong.
|
||||||
|
|
||||||
|
void Constraint::setPreparedOverload(PreparedOverload *preparedOverload) {
|
||||||
|
ASSERT(Kind == ConstraintKind::BindOverload);
|
||||||
|
|
||||||
|
// We can only set a prepared overload at most once in normal
|
||||||
|
// type checking, and then once in salvage.
|
||||||
|
ASSERT(!Overload.Prepared ||
|
||||||
|
(!Overload.Prepared->wasForDiagnostics() &&
|
||||||
|
preparedOverload->wasForDiagnostics()));
|
||||||
|
|
||||||
|
Overload.Prepared = preparedOverload;
|
||||||
|
}
|
||||||
@@ -2887,7 +2887,8 @@ ConstraintSystem::prepareOverloadImpl(OverloadChoice choice,
|
|||||||
|
|
||||||
PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
|
PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
|
||||||
DeclContext *useDC,
|
DeclContext *useDC,
|
||||||
ConstraintLocator *locator) {
|
ConstraintLocator *locator,
|
||||||
|
bool forDiagnostics) {
|
||||||
ASSERT(!PreparingOverload);
|
ASSERT(!PreparingOverload);
|
||||||
PreparingOverload = true;
|
PreparingOverload = true;
|
||||||
|
|
||||||
@@ -2903,7 +2904,8 @@ PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
|
|||||||
auto size = PreparedOverload::totalSizeToAlloc<PreparedOverload::Change>(count);
|
auto size = PreparedOverload::totalSizeToAlloc<PreparedOverload::Change>(count);
|
||||||
auto mem = Allocator.Allocate(size, alignof(PreparedOverload));
|
auto mem = Allocator.Allocate(size, alignof(PreparedOverload));
|
||||||
|
|
||||||
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes);
|
return new (mem) PreparedOverload(openedType, thrownErrorType, builder.Changes,
|
||||||
|
forDiagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstraintSystem::resolveOverload(OverloadChoice choice, DeclContext *useDC,
|
void ConstraintSystem::resolveOverload(OverloadChoice choice, DeclContext *useDC,
|
||||||
|
|||||||
Reference in New Issue
Block a user