mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Avoid copying BindingSets
They're stored inside the ConstraintGraphNode now, so returning a `const BindingSet *` from within determineBestBindings() should be safe.
This commit is contained in:
@@ -385,6 +385,10 @@ public:
|
||||
BindingSet(ConstraintSystem &CS, TypeVariableType *TypeVar,
|
||||
const PotentialBindings &info);
|
||||
|
||||
BindingSet(BindingSet &&other) = default;
|
||||
|
||||
BindingSet(const BindingSet &other) = delete;
|
||||
|
||||
ConstraintSystem &getConstraintSystem() const { return CS; }
|
||||
|
||||
TypeVariableType *getTypeVariable() const { return TypeVar; }
|
||||
|
||||
@@ -5270,7 +5270,7 @@ public:
|
||||
|
||||
/// Determine whether given type variable with its set of bindings is viable
|
||||
/// to be attempted on the next step of the solver.
|
||||
std::optional<BindingSet> determineBestBindings(
|
||||
const BindingSet *determineBestBindings(
|
||||
llvm::function_ref<void(const BindingSet &)> onCandidate);
|
||||
|
||||
/// Get bindings for the given type variable based on current
|
||||
@@ -6200,7 +6200,7 @@ class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
|
||||
public:
|
||||
using Element = TypeVariableBinding;
|
||||
|
||||
TypeVarBindingProducer(BindingSet &bindings);
|
||||
TypeVarBindingProducer(const BindingSet &bindings);
|
||||
|
||||
/// Retrieve a set of bindings available in the current state.
|
||||
ArrayRef<Binding> getCurrentBindings() const { return Bindings; }
|
||||
|
||||
@@ -1180,7 +1180,7 @@ bool BindingSet::operator<(const BindingSet &other) {
|
||||
return isPotentiallyIncomplete() < other.isPotentiallyIncomplete();
|
||||
}
|
||||
|
||||
std::optional<BindingSet> ConstraintSystem::determineBestBindings(
|
||||
const BindingSet *ConstraintSystem::determineBestBindings(
|
||||
llvm::function_ref<void(const BindingSet &)> onCandidate) {
|
||||
// Look for potential type variable bindings.
|
||||
BindingSet *bestBindings = nullptr;
|
||||
@@ -1238,10 +1238,7 @@ std::optional<BindingSet> ConstraintSystem::determineBestBindings(
|
||||
bestBindings = &bindings;
|
||||
}
|
||||
|
||||
if (!bestBindings)
|
||||
return std::nullopt;
|
||||
|
||||
return std::optional(*bestBindings);
|
||||
return bestBindings;
|
||||
}
|
||||
|
||||
/// Find the set of type variables that are inferable from the given type.
|
||||
|
||||
@@ -263,7 +263,7 @@ StepResult ComponentStep::take(bool prevFailed) {
|
||||
SmallString<64> potentialBindings;
|
||||
llvm::raw_svector_ostream bos(potentialBindings);
|
||||
|
||||
auto bestBindings = CS.determineBestBindings([&](const BindingSet &bindings) {
|
||||
const auto *bestBindings = CS.determineBestBindings([&](const BindingSet &bindings) {
|
||||
if (CS.isDebugMode() && bindings.hasViableBindings()) {
|
||||
bos.indent(CS.solverState->getCurrentIndent() + 2);
|
||||
bos << "(";
|
||||
|
||||
@@ -540,7 +540,7 @@ class TypeVariableStep final : public BindingStep<TypeVarBindingProducer> {
|
||||
bool SawFirstLiteralConstraint = false;
|
||||
|
||||
public:
|
||||
TypeVariableStep(BindingContainer &bindings,
|
||||
TypeVariableStep(const BindingContainer &bindings,
|
||||
SmallVectorImpl<Solution> &solutions)
|
||||
: BindingStep(bindings.getConstraintSystem(), {bindings}, solutions),
|
||||
TypeVar(bindings.getTypeVariable()) {}
|
||||
|
||||
@@ -5309,7 +5309,7 @@ ConstraintSystem::inferKeyPathLiteralCapability(KeyPathExpr *keyPath) {
|
||||
return success(mutability, isSendable);
|
||||
}
|
||||
|
||||
TypeVarBindingProducer::TypeVarBindingProducer(BindingSet &bindings)
|
||||
TypeVarBindingProducer::TypeVarBindingProducer(const BindingSet &bindings)
|
||||
: BindingProducer(bindings.getConstraintSystem(),
|
||||
bindings.getTypeVariable()->getImpl().getLocator()),
|
||||
TypeVar(bindings.getTypeVariable()), CanBeNil(bindings.canBeNil()) {
|
||||
|
||||
@@ -196,7 +196,7 @@ TEST_F(SemaTest, TestTransitiveProtocolInference) {
|
||||
cs.getConstraintLocator({}, LocatorPathElt::ContextualType(
|
||||
CTP_Initialization)));
|
||||
|
||||
auto bindings = inferBindings(cs, typeVar);
|
||||
auto &bindings = inferBindings(cs, typeVar);
|
||||
ASSERT_TRUE(bindings.getConformanceRequirements().empty());
|
||||
ASSERT_TRUE(bool(bindings.TransitiveProtocols));
|
||||
verifyProtocolInferenceResults(*bindings.TransitiveProtocols,
|
||||
@@ -218,7 +218,7 @@ TEST_F(SemaTest, TestTransitiveProtocolInference) {
|
||||
cs.addConstraint(ConstraintKind::Conversion, typeVar, GPT1,
|
||||
cs.getConstraintLocator({}));
|
||||
|
||||
auto bindings = inferBindings(cs, typeVar);
|
||||
auto &bindings = inferBindings(cs, typeVar);
|
||||
ASSERT_TRUE(bindings.getConformanceRequirements().empty());
|
||||
ASSERT_TRUE(bool(bindings.TransitiveProtocols));
|
||||
verifyProtocolInferenceResults(*bindings.TransitiveProtocols,
|
||||
@@ -281,10 +281,10 @@ TEST_F(SemaTest, TestComplexTransitiveProtocolInference) {
|
||||
cs.addConstraint(ConstraintKind::Equal, typeVar1, typeVar5, nilLocator);
|
||||
cs.addConstraint(ConstraintKind::Conversion, typeVar5, typeVar6, nilLocator);
|
||||
|
||||
auto bindingsForT1 = inferBindings(cs, typeVar1);
|
||||
auto bindingsForT2 = inferBindings(cs, typeVar2);
|
||||
auto bindingsForT3 = inferBindings(cs, typeVar3);
|
||||
auto bindingsForT5 = inferBindings(cs, typeVar5);
|
||||
auto &bindingsForT1 = inferBindings(cs, typeVar1);
|
||||
auto &bindingsForT2 = inferBindings(cs, typeVar2);
|
||||
auto &bindingsForT3 = inferBindings(cs, typeVar3);
|
||||
auto &bindingsForT5 = inferBindings(cs, typeVar5);
|
||||
|
||||
ASSERT_TRUE(bool(bindingsForT1.TransitiveProtocols));
|
||||
verifyProtocolInferenceResults(*bindingsForT1.TransitiveProtocols,
|
||||
@@ -335,7 +335,7 @@ TEST_F(SemaTest, TestTransitiveProtocolInferenceThroughEquivalenceChains) {
|
||||
cs.addConstraint(ConstraintKind::ConformsTo, typeVar2, protocolTy0, nilLocator);
|
||||
cs.addConstraint(ConstraintKind::ConformsTo, typeVar3, protocolTy1, nilLocator);
|
||||
|
||||
auto bindings = inferBindings(cs, typeVar0);
|
||||
auto &bindings = inferBindings(cs, typeVar0);
|
||||
|
||||
ASSERT_TRUE(bool(bindings.TransitiveProtocols));
|
||||
verifyProtocolInferenceResults(*bindings.TransitiveProtocols,
|
||||
|
||||
@@ -124,8 +124,8 @@ ProtocolType *SemaTest::createProtocol(llvm::StringRef protocolName,
|
||||
return ProtocolType::get(PD, parent, Context);
|
||||
}
|
||||
|
||||
BindingSet SemaTest::inferBindings(ConstraintSystem &cs,
|
||||
TypeVariableType *typeVar) {
|
||||
const BindingSet &SemaTest::inferBindings(ConstraintSystem &cs,
|
||||
TypeVariableType *typeVar) {
|
||||
for (auto *typeVar : cs.getTypeVariables()) {
|
||||
auto &node = cs.getConstraintGraph()[typeVar];
|
||||
node.resetBindingSet();
|
||||
|
||||
@@ -80,8 +80,8 @@ protected:
|
||||
ProtocolType *createProtocol(llvm::StringRef protocolName,
|
||||
Type parent = Type());
|
||||
|
||||
static BindingSet inferBindings(ConstraintSystem &cs,
|
||||
TypeVariableType *typeVar);
|
||||
static const BindingSet &inferBindings(ConstraintSystem &cs,
|
||||
TypeVariableType *typeVar);
|
||||
};
|
||||
|
||||
} // end namespace unittest
|
||||
|
||||
Reference in New Issue
Block a user