@@ -8817,14 +8817,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8817
8817
8818
8818
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
8819
8819
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 {
8822
8823
if (restriction != ConversionRestrictionKind::PointerToPointer)
8823
8824
increaseScore(ScoreKind::SK_ValueToPointerConversion);
8824
8825
8825
8826
auto result =
8826
- matchTypes(baseType1, baseType2, ConstraintKind::BindToPointerType ,
8827
- subflags, locator);
8827
+ matchTypes(baseType1.getPointer() , baseType2.getPointer() ,
8828
+ ConstraintKind::BindToPointerType, subflags, locator);
8828
8829
8829
8830
if (!(result.isFailure() && shouldAttemptFixes()))
8830
8831
return result;
@@ -8837,13 +8838,14 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8837
8838
case ConversionRestrictionKind::InoutToPointer: {
8838
8839
ptr2 = type2->lookThroughAllOptionalTypes()->castTo<BoundGenericType>();
8839
8840
ptr1 = BoundGenericType::get(ptr2->getDecl(), ptr2->getParent(),
8840
- {baseType1});
8841
+ {baseType1.getPointer() });
8841
8842
break;
8842
8843
}
8843
8844
8844
8845
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>();
8847
8849
break;
8848
8850
8849
8851
default:
@@ -8852,7 +8854,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
8852
8854
8853
8855
auto *fix = GenericArgumentsMismatch::create(*this, ptr1, ptr2, {0},
8854
8856
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;
8856
8866
};
8857
8867
8858
8868
auto fixContextualFailure = [&](Type fromType, Type toType,
@@ -9040,7 +9050,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
9040
9050
9041
9051
increaseScore(SK_ValueToOptional, ptr2.getInt());
9042
9052
9043
- return matchPointerBaseTypes(baseType1, ptr2.getPointer() );
9053
+ return matchPointerBaseTypes({ baseType1, 0}, ptr2);
9044
9054
}
9045
9055
9046
9056
// String ===> UnsafePointer<[U]Int8>
@@ -9101,7 +9111,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
9101
9111
9102
9112
increaseScore(SK_ValueToOptional, ptr2.getInt());
9103
9113
9104
- return matchPointerBaseTypes(baseType1, ptr2.getPointer() );
9114
+ return matchPointerBaseTypes({ baseType1, 0}, ptr2);
9105
9115
}
9106
9116
9107
9117
// T <p U ===> UnsafeMutablePointer<T> <a UnsafeMutablePointer<U>
@@ -9112,7 +9122,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
9112
9122
auto ptr1 = getBaseTypeForPointer(t1);
9113
9123
auto ptr2 = getBaseTypeForPointer(t2);
9114
9124
9115
- return matchPointerBaseTypes(ptr1.getPointer() , ptr2.getPointer() );
9125
+ return matchPointerBaseTypes(ptr1, ptr2);
9116
9126
}
9117
9127
9118
9128
// T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>
0 commit comments