diff --git a/include/swift/Sema/CSBindings.h b/include/swift/Sema/CSBindings.h index 1f2b1bff1d8..6fada3ed980 100644 --- a/include/swift/Sema/CSBindings.h +++ b/include/swift/Sema/CSBindings.h @@ -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; } @@ -568,8 +572,11 @@ public: /// requirements down the subtype or equivalence chain. void inferTransitiveProtocolRequirements(); - /// Check whether the given binding set covers any of the - /// literal protocols associated with this type variable. + /// Check whether the given binding set covers any of the literal protocols + /// associated with this type variable. The idea is that if a type variable + /// has a binding like Int and also it has a conformance requirement to + /// ExpressibleByIntegerLitral, we can avoid attempting the default type of + /// that literal literal if we already attempted Int. void determineLiteralCoverage(); /// Finalize binding computation for key path type variables. diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index b6b2ad4e7c8..a3a8c3b70af 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -95,10 +95,6 @@ Type typeCheckParameterDefault(Expr *&, DeclContext *, Type, bool, bool); } // end namespace swift -/// Allocate memory within the given constraint system. -void *operator new(size_t bytes, swift::constraints::ConstraintSystem& cs, - size_t alignment = 8); - namespace swift { /// Specify how we handle the binding of underconstrained (free) type variables @@ -5270,7 +5266,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 determineBestBindings( + const BindingSet *determineBestBindings( llvm::function_ref onCandidate); /// Get bindings for the given type variable based on current @@ -6200,7 +6196,7 @@ class TypeVarBindingProducer : public BindingProducer { public: using Element = TypeVariableBinding; - TypeVarBindingProducer(BindingSet &bindings); + TypeVarBindingProducer(const BindingSet &bindings); /// Retrieve a set of bindings available in the current state. ArrayRef getCurrentBindings() const { return Bindings; } diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index fc46bd46a0f..8e900fbb25c 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1180,7 +1180,7 @@ bool BindingSet::operator<(const BindingSet &other) { return isPotentiallyIncomplete() < other.isPotentiallyIncomplete(); } -std::optional ConstraintSystem::determineBestBindings( +const BindingSet *ConstraintSystem::determineBestBindings( llvm::function_ref onCandidate) { // Look for potential type variable bindings. BindingSet *bestBindings = nullptr; @@ -1238,10 +1238,7 @@ std::optional 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. diff --git a/lib/Sema/CSStep.cpp b/lib/Sema/CSStep.cpp index 26b8dbf26f8..e4f8e5e1280 100644 --- a/lib/Sema/CSStep.cpp +++ b/lib/Sema/CSStep.cpp @@ -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 << "("; diff --git a/lib/Sema/CSStep.h b/lib/Sema/CSStep.h index df92850ea2b..7c40af24993 100644 --- a/lib/Sema/CSStep.h +++ b/lib/Sema/CSStep.h @@ -540,7 +540,7 @@ class TypeVariableStep final : public BindingStep { bool SawFirstLiteralConstraint = false; public: - TypeVariableStep(BindingContainer &bindings, + TypeVariableStep(const BindingContainer &bindings, SmallVectorImpl &solutions) : BindingStep(bindings.getConstraintSystem(), {bindings}, solutions), TypeVar(bindings.getTypeVariable()) {} diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index bd4d02dc047..a7675254f31 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -1141,7 +1141,7 @@ Constraint::getTrailingClosureMatching() const { void *Constraint::operator new(size_t bytes, ConstraintSystem& cs, size_t alignment) { - return ::operator new (bytes, cs, alignment); + return cs.getAllocator().Allocate(bytes, alignment); } // FIXME: Perhaps we should store the Constraint -> PreparedOverload mapping diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index ed8539bbd17..b0d0659f091 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -5323,7 +5323,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()) { diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 2456d82cebb..3fd49101874 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -214,11 +214,6 @@ bool TypeVariableType::Implementation::isTernary() const { return locator && locator->directlyAt(); } -void *operator new(size_t bytes, ConstraintSystem& cs, - size_t alignment) { - return cs.getAllocator().Allocate(bytes, alignment); -} - bool constraints::computeTupleShuffle(TupleType *fromTuple, TupleType *toTuple, SmallVectorImpl &sources) { diff --git a/unittests/Sema/BindingInferenceTests.cpp b/unittests/Sema/BindingInferenceTests.cpp index eef3bb841ac..3791eef8bcc 100644 --- a/unittests/Sema/BindingInferenceTests.cpp +++ b/unittests/Sema/BindingInferenceTests.cpp @@ -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, diff --git a/unittests/Sema/SemaFixture.cpp b/unittests/Sema/SemaFixture.cpp index 0600e9ad592..b4fc3c5fd00 100644 --- a/unittests/Sema/SemaFixture.cpp +++ b/unittests/Sema/SemaFixture.cpp @@ -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(); diff --git a/unittests/Sema/SemaFixture.h b/unittests/Sema/SemaFixture.h index 715978082d4..077dba1e5fc 100644 --- a/unittests/Sema/SemaFixture.h +++ b/unittests/Sema/SemaFixture.h @@ -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