@@ -6589,9 +6589,18 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
65896589 // Only try an inout-to-pointer conversion if we know it's not
65906590 // an array being converted to a raw pointer type. Such
65916591 // conversions can only use array-to-pointer.
6592- if (!baseIsArray || !isRawPointerKind(pointerKind))
6592+ if (!baseIsArray || !isRawPointerKind(pointerKind)) {
65936593 conversionsOrFixes.push_back(
65946594 ConversionRestrictionKind::InoutToPointer);
6595+
6596+ // If regular inout-to-pointer conversion doesn't work,
6597+ // let's try C pointer conversion that has special semantics
6598+ // for imported declarations.
6599+ if (isArgumentOfImportedDecl(locator)) {
6600+ conversionsOrFixes.push_back(
6601+ ConversionRestrictionKind::InoutToCPointer);
6602+ }
6603+ }
65956604 }
65966605 }
65976606
@@ -12222,6 +12231,35 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1222212231 case ConversionRestrictionKind::PointerToCPointer:
1222312232 return simplifyPointerToCPointerRestriction(type1, type2, flags, locator);
1222412233
12234+ case ConversionRestrictionKind::InoutToCPointer: {
12235+ SmallVector<Type, 2> optionals;
12236+
12237+ auto ptr2 =
12238+ type2->getDesugaredType()->lookThroughAllOptionalTypes(optionals);
12239+
12240+ increaseScore(SK_ValueToOptional, optionals.size());
12241+
12242+ PointerTypeKind pointerKind;
12243+ (void)ptr2->getAnyPointerElementType(pointerKind);
12244+
12245+ auto baseType1 = type1->getInOutObjectType();
12246+
12247+ Type ptr1;
12248+ // The right-hand size is a raw pointer, so let's use `UnsafeMutablePointer`
12249+ // for the `inout` type.
12250+ if (pointerKind == PTK_UnsafeRawPointer ||
12251+ pointerKind == PTK_UnsafeMutableRawPointer) {
12252+ ptr1 = BoundGenericType::get(Context.getUnsafeMutablePointerDecl(),
12253+ /*parent=*/nullptr, {baseType1});
12254+ } else {
12255+ ptr1 = baseType1->wrapInPointer(pointerKind);
12256+ }
12257+
12258+ assert(ptr1);
12259+
12260+ return simplifyPointerToCPointerRestriction(ptr1, ptr2, flags, locator);
12261+ }
12262+
1222512263 // T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>
1222612264 case ConversionRestrictionKind::ArrayUpcast: {
1222712265 Type baseType1 = *isArrayType(type1);
0 commit comments