@@ -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