[ConstraintSystem] NFC: Extract Swift -> C pointer conversion simplification into a separate method

This commit is contained in:
Pavel Yaskevich
2021-08-12 13:00:12 -07:00
parent 416388191f
commit f368e5a7b6
2 changed files with 89 additions and 77 deletions

View File

@@ -11152,83 +11152,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
return matchPointerBaseTypes(ptr1, ptr2);
}
case ConversionRestrictionKind::PointerToCPointer: {
auto &ctx = getASTContext();
PointerTypeKind swiftPtrKind, cPtrKind;
auto swiftPtr =
type1->lookThroughAllOptionalTypes()->getAnyPointerElementType(
swiftPtrKind);
auto cPtr = type2->lookThroughAllOptionalTypes()->getAnyPointerElementType(
cPtrKind);
// Unsafe[Mutable]RawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
if (swiftPtrKind == PTK_UnsafeRawPointer ||
swiftPtrKind == PTK_UnsafeMutableRawPointer) {
// Since it's a C pointer on parameter side it would always
// be fully resolved.
if (cPtr->isInt8() || cPtr->isUInt8())
return SolutionKind::Solved;
} else {
// Unsafe[Mutable]Pointer<T> -> Unsafe[Mutable]Pointer<[U]Int8>
if (cPtr->isInt8() || cPtr->isUInt8()) {
// <T> can default to the type of C pointer.
addConstraint(
ConstraintKind::Defaultable, swiftPtr, cPtr,
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
return SolutionKind::Solved;
}
auto elementLoc =
locator.withPathElement(LocatorPathElt::GenericArgument(0));
// Unsafe[Mutable]Pointer<Int{8, 16, ...}> <->
// Unsafe[Mutable]Pointer<UInt{8, 16, ...}>
if (swiftPtr->isInt() || swiftPtr->isUInt()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt() ? ctx.getIntType() : ctx.getUIntType(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt8() || swiftPtr->isUInt8()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt8() ? ctx.getInt8Type()
: ctx.getUInt8Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt16() || swiftPtr->isUInt16()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt16() ? ctx.getInt16Type()
: ctx.getUInt16Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt32() || swiftPtr->isUInt32()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt32() ? ctx.getInt32Type()
: ctx.getUInt32Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt64() || swiftPtr->isUInt64()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt64() ? ctx.getInt64Type()
: ctx.getUInt64Type(),
elementLoc);
return SolutionKind::Solved;
}
}
return SolutionKind::Error;
}
case ConversionRestrictionKind::PointerToCPointer:
return simplifyPointerToCPointerRestriction(type1, type2, flags, locator);
// T < U or T is bridged to V where V < U ===> Array<T> <c Array<U>
case ConversionRestrictionKind::ArrayUpcast: {
@@ -11456,6 +11381,87 @@ ConstraintSystem::simplifyRestrictedConstraint(
llvm_unreachable("Unhandled SolutionKind in switch.");
}
ConstraintSystem::SolutionKind
ConstraintSystem::simplifyPointerToCPointerRestriction(
Type type1, Type type2, TypeMatchOptions flags,
ConstraintLocatorBuilder locator) {
auto &ctx = getASTContext();
PointerTypeKind swiftPtrKind, cPtrKind;
auto swiftPtr =
type1->lookThroughAllOptionalTypes()->getAnyPointerElementType(
swiftPtrKind);
auto cPtr =
type2->lookThroughAllOptionalTypes()->getAnyPointerElementType(cPtrKind);
// Unsafe[Mutable]RawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
if (swiftPtrKind == PTK_UnsafeRawPointer ||
swiftPtrKind == PTK_UnsafeMutableRawPointer) {
// Since it's a C pointer on parameter side it would always
// be fully resolved.
if (cPtr->isInt8() || cPtr->isUInt8())
return SolutionKind::Solved;
} else {
// Unsafe[Mutable]Pointer<T> -> Unsafe[Mutable]Pointer<[U]Int8>
if (cPtr->isInt8() || cPtr->isUInt8()) {
// <T> can default to the type of C pointer.
addConstraint(
ConstraintKind::Defaultable, swiftPtr, cPtr,
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
return SolutionKind::Solved;
}
auto elementLoc =
locator.withPathElement(LocatorPathElt::GenericArgument(0));
// Unsafe[Mutable]Pointer<Int{8, 16, ...}> <->
// Unsafe[Mutable]Pointer<UInt{8, 16, ...}>
if (swiftPtr->isInt() || swiftPtr->isUInt()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt() ? ctx.getIntType() : ctx.getUIntType(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt8() || swiftPtr->isUInt8()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt8() ? ctx.getInt8Type()
: ctx.getUInt8Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt16() || swiftPtr->isUInt16()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt16() ? ctx.getInt16Type()
: ctx.getUInt16Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt32() || swiftPtr->isUInt32()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt32() ? ctx.getInt32Type()
: ctx.getUInt32Type(),
elementLoc);
return SolutionKind::Solved;
}
if (swiftPtr->isInt64() || swiftPtr->isUInt64()) {
addConstraint(ConstraintKind::Equal, cPtr,
swiftPtr->isUInt64() ? ctx.getInt64Type()
: ctx.getUInt64Type(),
elementLoc);
return SolutionKind::Solved;
}
}
return SolutionKind::Error;
}
static bool isAugmentingFix(ConstraintFix *fix) {
switch (fix->getKind()) {
case FixKind::TreatRValueAsLValue: