mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CS] Handle packs in increaseScoreForGenericParamPointerConversion
Missed this in my original patch, handle pack parameters the same as regular generic parameters, ensuring we don't prefer a pack overload over a generic overload just because there are pointer conversions involved. Note this doesn't fix the wider issue of rdar://122011759, I'm planning on looking into that in a follow-up.
This commit is contained in:
@@ -15421,7 +15421,23 @@ static void increaseScoreForGenericParamPointerConversion(
|
||||
return;
|
||||
|
||||
// Check to see if the parameter is a generic parameter, or dependent member.
|
||||
auto paramTy = param->getInterfaceType()->lookThroughAllOptionalTypes();
|
||||
// Look though optionals and pack expansions.
|
||||
auto paramTy = param->getInterfaceType();
|
||||
while (true) {
|
||||
paramTy = paramTy->lookThroughAllOptionalTypes();
|
||||
if (auto packExpansion = paramTy->getAs<PackExpansionType>()) {
|
||||
paramTy = packExpansion->getPatternType();
|
||||
continue;
|
||||
}
|
||||
// Also look through "vanishing" tuples.
|
||||
if (auto *tupleTy = paramTy->getAs<TupleType>()) {
|
||||
if (tupleTy->getNumElements() == 1 && !tupleTy->getElement(0).hasName()) {
|
||||
paramTy = tupleTy->getElement(0).getType();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!paramTy->isTypeParameter())
|
||||
return;
|
||||
|
||||
|
||||
@@ -116,3 +116,30 @@ func testGenericPointerConversions(
|
||||
// Make sure this is ambiguous.
|
||||
ptr.foo(chars) // expected-error {{ambiguous use of 'foo'}}
|
||||
}
|
||||
|
||||
// Make sure we prefer non-pack overloads when pointer conversions are involved.
|
||||
func testOverloadedPackPointerConversions() {
|
||||
func takesPtr(_ ptr: UnsafePointer<CChar>) {}
|
||||
|
||||
// Deprecation does not impact solution score, so we can use it to ensure
|
||||
// we don't pick it.
|
||||
@available(*, deprecated, message: "shouldn't have picked this overload")
|
||||
func packOverloaded1<each T, R>(_ xs: repeat each T, fn: (repeat each T) -> R?) {}
|
||||
func packOverloaded1<T, R>(_ x: T, fn: (T) -> R?) {}
|
||||
packOverloaded1("") { takesPtr($0) }
|
||||
|
||||
@available(*, deprecated, message: "shouldn't have picked this overload")
|
||||
func packOverloaded2<each T, R>(_ xs: (repeat each T)?, fn: (repeat each T) -> R?) {}
|
||||
func packOverloaded2<T, R>(_ x: T?, fn: (T) -> R?) {}
|
||||
packOverloaded2("") { takesPtr($0) }
|
||||
|
||||
@available(*, deprecated, message: "shouldn't have picked this overload")
|
||||
func packOverloaded3<each T, R>(_ xs: repeat (each T)?, fn: (repeat each T) -> R?) {}
|
||||
func packOverloaded3<T, R>(_ x: T?, fn: (T) -> R?) {}
|
||||
packOverloaded3("") { takesPtr($0) }
|
||||
|
||||
@available(*, deprecated, message: "shouldn't have picked this overload")
|
||||
func packOverloaded4<each T, R>(_ xs: (repeat (each T)?)?, fn: (repeat each T) -> R?) {}
|
||||
func packOverloaded4<T, R>(_ x: T??, fn: (T) -> R?) {}
|
||||
packOverloaded4("") { takesPtr($0) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user