mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Remove unnecessary level of indentation in matchTypes()
This commit is contained in:
@@ -8098,191 +8098,189 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
|
||||
}
|
||||
}
|
||||
|
||||
if (kind >= ConstraintKind::Conversion) {
|
||||
// Pointer arguments can be converted from pointer-compatible types.
|
||||
if (kind >= ConstraintKind::ArgumentConversion) {
|
||||
// It is never legal to form an autoclosure that results in these
|
||||
// implicit conversions to pointer types.
|
||||
bool isAutoClosureArgument = locator.isForAutoclosureResult();
|
||||
|
||||
// Pointer arguments can be converted from pointer-compatible types.
|
||||
if (kind >= ConstraintKind::ArgumentConversion) {
|
||||
Type unwrappedType2 = type2;
|
||||
bool type2IsOptional = false;
|
||||
if (Type unwrapped = type2->getOptionalObjectType()) {
|
||||
type2IsOptional = true;
|
||||
unwrappedType2 = unwrapped;
|
||||
}
|
||||
PointerTypeKind pointerKind;
|
||||
if (Type pointeeTy =
|
||||
unwrappedType2->getAnyPointerElementType(pointerKind)) {
|
||||
switch (pointerKind) {
|
||||
case PTK_UnsafeRawPointer:
|
||||
case PTK_UnsafeMutableRawPointer:
|
||||
case PTK_UnsafePointer:
|
||||
case PTK_UnsafeMutablePointer:
|
||||
// UnsafeMutablePointer can be converted from an inout reference to a
|
||||
// scalar or array.
|
||||
if (auto inoutType1 = dyn_cast<InOutType>(desugar1)) {
|
||||
Type unwrappedType2 = type2;
|
||||
bool type2IsOptional = false;
|
||||
if (Type unwrapped = type2->getOptionalObjectType()) {
|
||||
type2IsOptional = true;
|
||||
unwrappedType2 = unwrapped;
|
||||
}
|
||||
PointerTypeKind pointerKind;
|
||||
if (Type pointeeTy =
|
||||
unwrappedType2->getAnyPointerElementType(pointerKind)) {
|
||||
switch (pointerKind) {
|
||||
case PTK_UnsafeRawPointer:
|
||||
case PTK_UnsafeMutableRawPointer:
|
||||
case PTK_UnsafePointer:
|
||||
case PTK_UnsafeMutablePointer:
|
||||
// UnsafeMutablePointer can be converted from an inout reference to a
|
||||
// scalar or array.
|
||||
if (auto inoutType1 = dyn_cast<InOutType>(desugar1)) {
|
||||
if (!isAutoClosureArgument) {
|
||||
auto inoutBaseType = getFixedTypeRecursive(
|
||||
inoutType1->getInOutObjectType(), /*wantRValue=*/true);
|
||||
|
||||
// Wait until the base type of `inout` is sufficiently resolved
|
||||
// before making any assessments regarding conversions.
|
||||
if (inoutBaseType->isTypeVariableOrMember())
|
||||
return formUnsolvedResult();
|
||||
|
||||
auto baseIsArray = inoutBaseType->isArray();
|
||||
|
||||
if (baseIsArray)
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::ArrayToPointer);
|
||||
|
||||
// Only try an inout-to-pointer conversion if we know it's not
|
||||
// an array being converted to a raw pointer type. Such
|
||||
// conversions can only use array-to-pointer.
|
||||
if (!baseIsArray || !isRawPointerKind(pointerKind)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::InoutToPointer);
|
||||
|
||||
// If regular inout-to-pointer conversion doesn't work,
|
||||
// let's try C pointer conversion that has special semantics
|
||||
// for imported declarations.
|
||||
if (isArgumentOfImportedDecl(locator)) {
|
||||
conversionsOrFixes.push_back(
|
||||
baseIsArray ? ConversionRestrictionKind::ArrayToCPointer
|
||||
: ConversionRestrictionKind::InoutToCPointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operators cannot use these implicit conversions.
|
||||
if (kind == ConstraintKind::ArgumentConversion) {
|
||||
// We can potentially convert from an UnsafeMutablePointer
|
||||
// of a different type, if we're a void pointer.
|
||||
Type unwrappedType1 = type1;
|
||||
bool type1IsOptional = false;
|
||||
if (Type unwrapped = type1->getOptionalObjectType()) {
|
||||
type1IsOptional = true;
|
||||
unwrappedType1 = unwrapped;
|
||||
}
|
||||
|
||||
// Don't handle normal optional-related conversions here.
|
||||
if (unwrappedType1->isEqual(unwrappedType2))
|
||||
break;
|
||||
|
||||
PointerTypeKind type1PointerKind;
|
||||
bool type1IsPointer{
|
||||
unwrappedType1->getAnyPointerElementType(type1PointerKind)};
|
||||
bool optionalityMatches = !type1IsOptional || type2IsOptional;
|
||||
if (type1IsPointer && optionalityMatches) {
|
||||
if (type1PointerKind == PTK_UnsafeMutablePointer) {
|
||||
// Favor an UnsafeMutablePointer-to-UnsafeMutablePointer
|
||||
// conversion.
|
||||
if (type1PointerKind != pointerKind)
|
||||
increaseScore(ScoreKind::SK_ValueToPointerConversion,
|
||||
locator);
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
}
|
||||
// UnsafeMutableRawPointer -> UnsafeRawPointer
|
||||
else if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
|
||||
pointerKind == PTK_UnsafeRawPointer) {
|
||||
if (type1PointerKind != pointerKind)
|
||||
increaseScore(ScoreKind::SK_ValueToPointerConversion,
|
||||
locator);
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
}
|
||||
}
|
||||
// UnsafePointer and UnsafeRawPointer can also be converted from an
|
||||
// array or string value, or a UnsafePointer or
|
||||
// AutoreleasingUnsafeMutablePointer.
|
||||
if (pointerKind == PTK_UnsafePointer
|
||||
|| pointerKind == PTK_UnsafeRawPointer) {
|
||||
if (!isAutoClosureArgument) {
|
||||
auto inoutBaseType = getFixedTypeRecursive(
|
||||
inoutType1->getInOutObjectType(), /*wantRValue=*/true);
|
||||
|
||||
// Wait until the base type of `inout` is sufficiently resolved
|
||||
// before making any assessments regarding conversions.
|
||||
if (inoutBaseType->isTypeVariableOrMember())
|
||||
return formUnsolvedResult();
|
||||
|
||||
auto baseIsArray = inoutBaseType->isArray();
|
||||
|
||||
if (baseIsArray)
|
||||
if (type1->isArray()) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::ArrayToPointer);
|
||||
|
||||
// Only try an inout-to-pointer conversion if we know it's not
|
||||
// an array being converted to a raw pointer type. Such
|
||||
// conversions can only use array-to-pointer.
|
||||
if (!baseIsArray || !isRawPointerKind(pointerKind)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::InoutToPointer);
|
||||
|
||||
// If regular inout-to-pointer conversion doesn't work,
|
||||
// If regular array-to-pointer conversion doesn't work,
|
||||
// let's try C pointer conversion that has special semantics
|
||||
// for imported declarations.
|
||||
if (isArgumentOfImportedDecl(locator)) {
|
||||
conversionsOrFixes.push_back(
|
||||
baseIsArray ? ConversionRestrictionKind::ArrayToCPointer
|
||||
: ConversionRestrictionKind::InoutToCPointer);
|
||||
ConversionRestrictionKind::ArrayToCPointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Operators cannot use these implicit conversions.
|
||||
if (kind == ConstraintKind::ArgumentConversion) {
|
||||
// We can potentially convert from an UnsafeMutablePointer
|
||||
// of a different type, if we're a void pointer.
|
||||
Type unwrappedType1 = type1;
|
||||
bool type1IsOptional = false;
|
||||
if (Type unwrapped = type1->getOptionalObjectType()) {
|
||||
type1IsOptional = true;
|
||||
unwrappedType1 = unwrapped;
|
||||
}
|
||||
// The pointer can be converted from a string, if the element
|
||||
// type is compatible.
|
||||
auto &ctx = getASTContext();
|
||||
if (type1->isString()) {
|
||||
auto baseTy = getFixedTypeRecursive(pointeeTy, false);
|
||||
|
||||
// Don't handle normal optional-related conversions here.
|
||||
if (unwrappedType1->isEqual(unwrappedType2))
|
||||
break;
|
||||
|
||||
PointerTypeKind type1PointerKind;
|
||||
bool type1IsPointer{
|
||||
unwrappedType1->getAnyPointerElementType(type1PointerKind)};
|
||||
bool optionalityMatches = !type1IsOptional || type2IsOptional;
|
||||
if (type1IsPointer && optionalityMatches) {
|
||||
if (type1PointerKind == PTK_UnsafeMutablePointer) {
|
||||
// Favor an UnsafeMutablePointer-to-UnsafeMutablePointer
|
||||
// conversion.
|
||||
if (type1PointerKind != pointerKind)
|
||||
increaseScore(ScoreKind::SK_ValueToPointerConversion,
|
||||
locator);
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
}
|
||||
// UnsafeMutableRawPointer -> UnsafeRawPointer
|
||||
else if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
|
||||
pointerKind == PTK_UnsafeRawPointer) {
|
||||
if (type1PointerKind != pointerKind)
|
||||
increaseScore(ScoreKind::SK_ValueToPointerConversion,
|
||||
locator);
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
}
|
||||
}
|
||||
// UnsafePointer and UnsafeRawPointer can also be converted from an
|
||||
// array or string value, or a UnsafePointer or
|
||||
// AutoreleasingUnsafeMutablePointer.
|
||||
if (pointerKind == PTK_UnsafePointer
|
||||
|| pointerKind == PTK_UnsafeRawPointer) {
|
||||
if (!isAutoClosureArgument) {
|
||||
if (type1->isArray()) {
|
||||
if (baseTy->isTypeVariableOrMember() ||
|
||||
isStringCompatiblePointerBaseType(ctx, baseTy))
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::ArrayToPointer);
|
||||
|
||||
// If regular array-to-pointer conversion doesn't work,
|
||||
// let's try C pointer conversion that has special semantics
|
||||
// for imported declarations.
|
||||
if (isArgumentOfImportedDecl(locator)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::ArrayToCPointer);
|
||||
}
|
||||
}
|
||||
|
||||
// The pointer can be converted from a string, if the element
|
||||
// type is compatible.
|
||||
auto &ctx = getASTContext();
|
||||
if (type1->isString()) {
|
||||
auto baseTy = getFixedTypeRecursive(pointeeTy, false);
|
||||
|
||||
if (baseTy->isTypeVariableOrMember() ||
|
||||
isStringCompatiblePointerBaseType(ctx, baseTy))
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::StringToPointer);
|
||||
}
|
||||
}
|
||||
|
||||
if (type1IsPointer && optionalityMatches &&
|
||||
(type1PointerKind == PTK_UnsafePointer ||
|
||||
type1PointerKind == PTK_AutoreleasingUnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
ConversionRestrictionKind::StringToPointer);
|
||||
}
|
||||
}
|
||||
|
||||
// If both sides are non-optional pointers, let's check whether
|
||||
// this argument supports Swift -> C pointer conversions.
|
||||
//
|
||||
// Do some light verification before recording restriction to
|
||||
// avoid allocating constraints for obviously invalid cases.
|
||||
if (type1IsPointer && !type1IsOptional && !type2IsOptional &&
|
||||
(shouldAttemptFixes() || isArgumentOfImportedDecl(locator))) {
|
||||
// UnsafeRawPointer -> UnsafePointer<[U]Int8>
|
||||
if (type1PointerKind == PTK_UnsafeRawPointer &&
|
||||
pointerKind == PTK_UnsafePointer) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
// UnsafeMutableRawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
|
||||
if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
|
||||
(pointerKind == PTK_UnsafePointer ||
|
||||
pointerKind == PTK_UnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
// Unsafe[Mutable]Pointer -> Unsafe[Mutable]Pointer
|
||||
if (type1PointerKind == PTK_UnsafePointer &&
|
||||
pointerKind == PTK_UnsafePointer) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
if (type1PointerKind == PTK_UnsafeMutablePointer &&
|
||||
(pointerKind == PTK_UnsafePointer ||
|
||||
pointerKind == PTK_UnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
if (type1IsPointer && optionalityMatches &&
|
||||
(type1PointerKind == PTK_UnsafePointer ||
|
||||
type1PointerKind == PTK_AutoreleasingUnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToPointer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTK_AutoreleasingUnsafeMutablePointer:
|
||||
// PTK_AutoreleasingUnsafeMutablePointer can be converted from an
|
||||
// inout reference to a scalar.
|
||||
if (!isAutoClosureArgument && type1->is<InOutType>()) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::InoutToPointer);
|
||||
// If both sides are non-optional pointers, let's check whether
|
||||
// this argument supports Swift -> C pointer conversions.
|
||||
//
|
||||
// Do some light verification before recording restriction to
|
||||
// avoid allocating constraints for obviously invalid cases.
|
||||
if (type1IsPointer && !type1IsOptional && !type2IsOptional &&
|
||||
(shouldAttemptFixes() || isArgumentOfImportedDecl(locator))) {
|
||||
// UnsafeRawPointer -> UnsafePointer<[U]Int8>
|
||||
if (type1PointerKind == PTK_UnsafeRawPointer &&
|
||||
pointerKind == PTK_UnsafePointer) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
// UnsafeMutableRawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
|
||||
if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
|
||||
(pointerKind == PTK_UnsafePointer ||
|
||||
pointerKind == PTK_UnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
// Unsafe[Mutable]Pointer -> Unsafe[Mutable]Pointer
|
||||
if (type1PointerKind == PTK_UnsafePointer &&
|
||||
pointerKind == PTK_UnsafePointer) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
|
||||
if (type1PointerKind == PTK_UnsafeMutablePointer &&
|
||||
(pointerKind == PTK_UnsafePointer ||
|
||||
pointerKind == PTK_UnsafeMutablePointer)) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::PointerToCPointer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PTK_AutoreleasingUnsafeMutablePointer:
|
||||
// PTK_AutoreleasingUnsafeMutablePointer can be converted from an
|
||||
// inout reference to a scalar.
|
||||
if (!isAutoClosureArgument && type1->is<InOutType>()) {
|
||||
conversionsOrFixes.push_back(
|
||||
ConversionRestrictionKind::InoutToPointer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user