Skip to content

Commit c884068

Browse files
committed
[ConstraintSystem] Tally implicit optional wraps into impact of pointer mismatch
Impact of cases where pointer types mismatch after implict optional wrap(s) should be higher than mismatch alone. Distinguishing that helps to disambiguate following case (and other similar ones) without using ranking: ```swift func foo(_: UnsafePointer<Int>) {} func foo(_: UnsafePointer<Int>?) {} func test(_ ptr: UnsafePointer<Float>) { foo(ptr) } ```
1 parent a676a37 commit c884068

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8817,14 +8817,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
88178817

88188818
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
88198819

8820-
auto matchPointerBaseTypes = [&](Type baseType1,
8821-
Type baseType2) -> SolutionKind {
8820+
auto matchPointerBaseTypes =
8821+
[&](llvm::PointerIntPair<Type, 3, unsigned> baseType1,
8822+
llvm::PointerIntPair<Type, 3, unsigned> baseType2) -> SolutionKind {
88228823
if (restriction != ConversionRestrictionKind::PointerToPointer)
88238824
increaseScore(ScoreKind::SK_ValueToPointerConversion);
88248825

88258826
auto result =
8826-
matchTypes(baseType1, baseType2, ConstraintKind::BindToPointerType,
8827-
subflags, locator);
8827+
matchTypes(baseType1.getPointer(), baseType2.getPointer(),
8828+
ConstraintKind::BindToPointerType, subflags, locator);
88288829

88298830
if (!(result.isFailure() && shouldAttemptFixes()))
88308831
return result;
@@ -8837,13 +8838,14 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
88378838
case ConversionRestrictionKind::InoutToPointer: {
88388839
ptr2 = type2->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
88398840
ptr1 = BoundGenericType::get(ptr2->getDecl(), ptr2->getParent(),
8840-
{baseType1});
8841+
{baseType1.getPointer()});
88418842
break;
88428843
}
88438844

88448845
case ConversionRestrictionKind::PointerToPointer:
8845-
ptr1 = type1->castTo<BoundGenericType>();
8846-
ptr2 = type2->castTo<BoundGenericType>();
8846+
// Original types could be wrapped into a different number of optional.
8847+
ptr1 = type1->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
8848+
ptr2 = type2->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
88478849
break;
88488850

88498851
default:
@@ -8852,7 +8854,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
88528854

88538855
auto *fix = GenericArgumentsMismatch::create(*this, ptr1, ptr2, {0},
88548856
getConstraintLocator(locator));
8855-
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
8857+
8858+
// It's possible to implicitly promote pointer into an optional
8859+
// before matching base types if other side is an optional, so
8860+
// score needs to account for number of such promotions.
8861+
int optionalWraps = baseType2.getInt() - baseType1.getInt();
8862+
return recordFix(fix,
8863+
/*impact=*/1 + abs(optionalWraps))
8864+
? SolutionKind::Error
8865+
: SolutionKind::Solved;
88568866
};
88578867

88588868
auto fixContextualFailure = [&](Type fromType, Type toType,
@@ -9040,7 +9050,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
90409050

90419051
increaseScore(SK_ValueToOptional, ptr2.getInt());
90429052

9043-
return matchPointerBaseTypes(baseType1, ptr2.getPointer());
9053+
return matchPointerBaseTypes({baseType1, 0}, ptr2);
90449054
}
90459055

90469056
// String ===> UnsafePointer<[U]Int8>
@@ -9101,7 +9111,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
91019111

91029112
increaseScore(SK_ValueToOptional, ptr2.getInt());
91039113

9104-
return matchPointerBaseTypes(baseType1, ptr2.getPointer());
9114+
return matchPointerBaseTypes({baseType1, 0}, ptr2);
91059115
}
91069116

91079117
// T <p U ===> UnsafeMutablePointer<T> <a UnsafeMutablePointer<U>
@@ -9112,7 +9122,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
91129122
auto ptr1 = getBaseTypeForPointer(t1);
91139123
auto ptr2 = getBaseTypeForPointer(t2);
91149124

9115-
return matchPointerBaseTypes(ptr1.getPointer(), ptr2.getPointer());
9125+
return matchPointerBaseTypes(ptr1, ptr2);
91169126
}
91179127

91189128
// T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>

0 commit comments

Comments
 (0)