Reapply "[ConstraintSystem] C++ Interop: Binding a string literal to std.string shouldn't increase the score"

This reverts commit 6852bc9834.

In addition to the original change, this makes sure that C++ `std::string` and Swift `String` are given distinct score, in order to prevent ambiguity which was causing build failures in some projects.

rdar://158439395
This commit is contained in:
Egor Zhdan
2025-12-08 18:15:06 +00:00
parent 51c1358778
commit 84e7f82363
6 changed files with 88 additions and 4 deletions

View File

@@ -257,10 +257,24 @@ void ConstraintSystem::assignFixedType(TypeVariableType *typeVar, Type type,
// If the protocol has a default type, check it.
if (auto defaultType = TypeChecker::getDefaultType(literalProtocol, DC)) {
// Check whether the nominal types match. This makes sure that we
// properly handle Array vs. Array<T>.
if (defaultType->getAnyNominal() != type->getAnyNominal()) {
increaseScore(SK_NonDefaultLiteral, locator);
auto isDefaultType = [&defaultType](Type type) {
// Check whether the nominal types match. This makes sure that we
// properly handle Array vs. Array<T>.
return defaultType->getAnyNominal() == type->getAnyNominal();
};
if (!isDefaultType(type)) {
// Treat `std.string` as a default type just like we do
// Swift standard library `String`. This helps to disambiguate
// operator overloads that use `std.string` vs. a custom C++
// type that conforms to `ExpressibleByStringLiteral` as well.
bool isCxxDefaultType =
literalProtocol->isSpecificProtocol(
KnownProtocolKind::ExpressibleByStringLiteral) &&
type->isCxxString();
increaseScore(SK_NonDefaultLiteral, locator,
isCxxDefaultType ? 1 : 2);
}
}