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