@@ -6591,9 +6591,18 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
65916591 // Only try an inout-to-pointer conversion if we know it's not
65926592 // an array being converted to a raw pointer type. Such
65936593 // conversions can only use array-to-pointer.
6594- if (!baseIsArray || !isRawPointerKind(pointerKind))
6594+ if (!baseIsArray || !isRawPointerKind(pointerKind)) {
65956595 conversionsOrFixes.push_back(
65966596 ConversionRestrictionKind::InoutToPointer);
6597+
6598+ // If regular inout-to-pointer conversion doesn't work,
6599+ // let's try C pointer conversion that has special semantics
6600+ // for imported declarations.
6601+ if (isArgumentOfImportedDecl(locator)) {
6602+ conversionsOrFixes.push_back(
6603+ ConversionRestrictionKind::InoutToCPointer);
6604+ }
6605+ }
65976606 }
65986607 }
65996608
@@ -12211,6 +12220,35 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1221112220 case ConversionRestrictionKind::PointerToCPointer:
1221212221 return simplifyPointerToCPointerRestriction(type1, type2, flags, locator);
1221312222
12223+ case ConversionRestrictionKind::InoutToCPointer: {
12224+ SmallVector<Type, 2> optionals;
12225+
12226+ auto ptr2 =
12227+ type2->getDesugaredType()->lookThroughAllOptionalTypes(optionals);
12228+
12229+ increaseScore(SK_ValueToOptional, optionals.size());
12230+
12231+ PointerTypeKind pointerKind;
12232+ (void)ptr2->getAnyPointerElementType(pointerKind);
12233+
12234+ auto baseType1 = type1->getInOutObjectType();
12235+
12236+ Type ptr1;
12237+ // The right-hand size is a raw pointer, so let's use `UnsafeMutablePointer`
12238+ // for the `inout` type.
12239+ if (pointerKind == PTK_UnsafeRawPointer ||
12240+ pointerKind == PTK_UnsafeMutableRawPointer) {
12241+ ptr1 = BoundGenericType::get(Context.getUnsafeMutablePointerDecl(),
12242+ /*parent=*/nullptr, {baseType1});
12243+ } else {
12244+ ptr1 = baseType1->wrapInPointer(pointerKind);
12245+ }
12246+
12247+ assert(ptr1);
12248+
12249+ return simplifyPointerToCPointerRestriction(ptr1, ptr2, flags, locator);
12250+ }
12251+
1221412252 // T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>
1221512253 case ConversionRestrictionKind::ArrayUpcast: {
1221612254 Type baseType1 = *isArrayType(type1);
0 commit comments