@@ -8098,191 +8098,189 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
80988098 }
80998099 }
81008100
8101- if (kind >= ConstraintKind::Conversion) {
8101+ // Pointer arguments can be converted from pointer-compatible types.
8102+ if (kind >= ConstraintKind::ArgumentConversion) {
81028103 // It is never legal to form an autoclosure that results in these
81038104 // implicit conversions to pointer types.
81048105 bool isAutoClosureArgument = locator.isForAutoclosureResult();
81058106
8106- // Pointer arguments can be converted from pointer-compatible types.
8107- if (kind >= ConstraintKind::ArgumentConversion) {
8108- Type unwrappedType2 = type2;
8109- bool type2IsOptional = false;
8110- if (Type unwrapped = type2->getOptionalObjectType()) {
8111- type2IsOptional = true;
8112- unwrappedType2 = unwrapped;
8113- }
8114- PointerTypeKind pointerKind;
8115- if (Type pointeeTy =
8116- unwrappedType2->getAnyPointerElementType(pointerKind)) {
8117- switch (pointerKind) {
8118- case PTK_UnsafeRawPointer:
8119- case PTK_UnsafeMutableRawPointer:
8120- case PTK_UnsafePointer:
8121- case PTK_UnsafeMutablePointer:
8122- // UnsafeMutablePointer can be converted from an inout reference to a
8123- // scalar or array.
8124- if (auto inoutType1 = dyn_cast<InOutType>(desugar1)) {
8125- if (!isAutoClosureArgument) {
8126- auto inoutBaseType = getFixedTypeRecursive(
8127- inoutType1->getInOutObjectType(), /*wantRValue=*/true);
8107+ Type unwrappedType2 = type2;
8108+ bool type2IsOptional = false;
8109+ if (Type unwrapped = type2->getOptionalObjectType()) {
8110+ type2IsOptional = true;
8111+ unwrappedType2 = unwrapped;
8112+ }
8113+ PointerTypeKind pointerKind;
8114+ if (Type pointeeTy =
8115+ unwrappedType2->getAnyPointerElementType(pointerKind)) {
8116+ switch (pointerKind) {
8117+ case PTK_UnsafeRawPointer:
8118+ case PTK_UnsafeMutableRawPointer:
8119+ case PTK_UnsafePointer:
8120+ case PTK_UnsafeMutablePointer:
8121+ // UnsafeMutablePointer can be converted from an inout reference to a
8122+ // scalar or array.
8123+ if (auto inoutType1 = dyn_cast<InOutType>(desugar1)) {
8124+ if (!isAutoClosureArgument) {
8125+ auto inoutBaseType = getFixedTypeRecursive(
8126+ inoutType1->getInOutObjectType(), /*wantRValue=*/true);
81288127
8129- // Wait until the base type of `inout` is sufficiently resolved
8130- // before making any assessments regarding conversions.
8131- if (inoutBaseType->isTypeVariableOrMember())
8132- return formUnsolvedResult();
8128+ // Wait until the base type of `inout` is sufficiently resolved
8129+ // before making any assessments regarding conversions.
8130+ if (inoutBaseType->isTypeVariableOrMember())
8131+ return formUnsolvedResult();
81338132
8134- auto baseIsArray = inoutBaseType->isArray();
8133+ auto baseIsArray = inoutBaseType->isArray();
81358134
8136- if (baseIsArray)
8135+ if (baseIsArray)
8136+ conversionsOrFixes.push_back(
8137+ ConversionRestrictionKind::ArrayToPointer);
8138+
8139+ // Only try an inout-to-pointer conversion if we know it's not
8140+ // an array being converted to a raw pointer type. Such
8141+ // conversions can only use array-to-pointer.
8142+ if (!baseIsArray || !isRawPointerKind(pointerKind)) {
8143+ conversionsOrFixes.push_back(
8144+ ConversionRestrictionKind::InoutToPointer);
8145+
8146+ // If regular inout-to-pointer conversion doesn't work,
8147+ // let's try C pointer conversion that has special semantics
8148+ // for imported declarations.
8149+ if (isArgumentOfImportedDecl(locator)) {
81378150 conversionsOrFixes.push_back(
8138- ConversionRestrictionKind::ArrayToPointer);
8151+ baseIsArray ? ConversionRestrictionKind::ArrayToCPointer
8152+ : ConversionRestrictionKind::InoutToCPointer);
8153+ }
8154+ }
8155+ }
8156+ }
81398157
8140- // Only try an inout-to-pointer conversion if we know it's not
8141- // an array being converted to a raw pointer type. Such
8142- // conversions can only use array-to-pointer.
8143- if (!baseIsArray || !isRawPointerKind(pointerKind)) {
8158+ // Operators cannot use these implicit conversions.
8159+ if (kind == ConstraintKind::ArgumentConversion) {
8160+ // We can potentially convert from an UnsafeMutablePointer
8161+ // of a different type, if we're a void pointer.
8162+ Type unwrappedType1 = type1;
8163+ bool type1IsOptional = false;
8164+ if (Type unwrapped = type1->getOptionalObjectType()) {
8165+ type1IsOptional = true;
8166+ unwrappedType1 = unwrapped;
8167+ }
8168+
8169+ // Don't handle normal optional-related conversions here.
8170+ if (unwrappedType1->isEqual(unwrappedType2))
8171+ break;
8172+
8173+ PointerTypeKind type1PointerKind;
8174+ bool type1IsPointer{
8175+ unwrappedType1->getAnyPointerElementType(type1PointerKind)};
8176+ bool optionalityMatches = !type1IsOptional || type2IsOptional;
8177+ if (type1IsPointer && optionalityMatches) {
8178+ if (type1PointerKind == PTK_UnsafeMutablePointer) {
8179+ // Favor an UnsafeMutablePointer-to-UnsafeMutablePointer
8180+ // conversion.
8181+ if (type1PointerKind != pointerKind)
8182+ increaseScore(ScoreKind::SK_ValueToPointerConversion,
8183+ locator);
8184+ conversionsOrFixes.push_back(
8185+ ConversionRestrictionKind::PointerToPointer);
8186+ }
8187+ // UnsafeMutableRawPointer -> UnsafeRawPointer
8188+ else if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
8189+ pointerKind == PTK_UnsafeRawPointer) {
8190+ if (type1PointerKind != pointerKind)
8191+ increaseScore(ScoreKind::SK_ValueToPointerConversion,
8192+ locator);
8193+ conversionsOrFixes.push_back(
8194+ ConversionRestrictionKind::PointerToPointer);
8195+ }
8196+ }
8197+ // UnsafePointer and UnsafeRawPointer can also be converted from an
8198+ // array or string value, or a UnsafePointer or
8199+ // AutoreleasingUnsafeMutablePointer.
8200+ if (pointerKind == PTK_UnsafePointer
8201+ || pointerKind == PTK_UnsafeRawPointer) {
8202+ if (!isAutoClosureArgument) {
8203+ if (type1->isArray()) {
81448204 conversionsOrFixes.push_back(
8145- ConversionRestrictionKind::InoutToPointer );
8205+ ConversionRestrictionKind::ArrayToPointer );
81468206
8147- // If regular inout -to-pointer conversion doesn't work,
8207+ // If regular array -to-pointer conversion doesn't work,
81488208 // let's try C pointer conversion that has special semantics
81498209 // for imported declarations.
81508210 if (isArgumentOfImportedDecl(locator)) {
81518211 conversionsOrFixes.push_back(
8152- baseIsArray ? ConversionRestrictionKind::ArrayToCPointer
8153- : ConversionRestrictionKind::InoutToCPointer);
8212+ ConversionRestrictionKind::ArrayToCPointer);
81548213 }
81558214 }
8156- }
8157- }
81588215
8159- // Operators cannot use these implicit conversions.
8160- if (kind == ConstraintKind::ArgumentConversion) {
8161- // We can potentially convert from an UnsafeMutablePointer
8162- // of a different type, if we're a void pointer.
8163- Type unwrappedType1 = type1;
8164- bool type1IsOptional = false;
8165- if (Type unwrapped = type1->getOptionalObjectType()) {
8166- type1IsOptional = true;
8167- unwrappedType1 = unwrapped;
8168- }
8216+ // The pointer can be converted from a string, if the element
8217+ // type is compatible.
8218+ auto &ctx = getASTContext();
8219+ if (type1->isString()) {
8220+ auto baseTy = getFixedTypeRecursive(pointeeTy, false);
81698221
8170- // Don't handle normal optional-related conversions here.
8171- if (unwrappedType1->isEqual(unwrappedType2))
8172- break;
8173-
8174- PointerTypeKind type1PointerKind;
8175- bool type1IsPointer{
8176- unwrappedType1->getAnyPointerElementType(type1PointerKind)};
8177- bool optionalityMatches = !type1IsOptional || type2IsOptional;
8178- if (type1IsPointer && optionalityMatches) {
8179- if (type1PointerKind == PTK_UnsafeMutablePointer) {
8180- // Favor an UnsafeMutablePointer-to-UnsafeMutablePointer
8181- // conversion.
8182- if (type1PointerKind != pointerKind)
8183- increaseScore(ScoreKind::SK_ValueToPointerConversion,
8184- locator);
8185- conversionsOrFixes.push_back(
8186- ConversionRestrictionKind::PointerToPointer);
8187- }
8188- // UnsafeMutableRawPointer -> UnsafeRawPointer
8189- else if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
8190- pointerKind == PTK_UnsafeRawPointer) {
8191- if (type1PointerKind != pointerKind)
8192- increaseScore(ScoreKind::SK_ValueToPointerConversion,
8193- locator);
8194- conversionsOrFixes.push_back(
8195- ConversionRestrictionKind::PointerToPointer);
8222+ if (baseTy->isTypeVariableOrMember() ||
8223+ isStringCompatiblePointerBaseType(ctx, baseTy))
8224+ conversionsOrFixes.push_back(
8225+ ConversionRestrictionKind::StringToPointer);
81968226 }
81978227 }
8198- // UnsafePointer and UnsafeRawPointer can also be converted from an
8199- // array or string value, or a UnsafePointer or
8200- // AutoreleasingUnsafeMutablePointer.
8201- if (pointerKind == PTK_UnsafePointer
8202- || pointerKind == PTK_UnsafeRawPointer) {
8203- if (!isAutoClosureArgument) {
8204- if (type1->isArray()) {
8205- conversionsOrFixes.push_back(
8206- ConversionRestrictionKind::ArrayToPointer);
8207-
8208- // If regular array-to-pointer conversion doesn't work,
8209- // let's try C pointer conversion that has special semantics
8210- // for imported declarations.
8211- if (isArgumentOfImportedDecl(locator)) {
8212- conversionsOrFixes.push_back(
8213- ConversionRestrictionKind::ArrayToCPointer);
8214- }
8215- }
8216-
8217- // The pointer can be converted from a string, if the element
8218- // type is compatible.
8219- auto &ctx = getASTContext();
8220- if (type1->isString()) {
8221- auto baseTy = getFixedTypeRecursive(pointeeTy, false);
82228228
8223- if (baseTy->isTypeVariableOrMember() ||
8224- isStringCompatiblePointerBaseType(ctx, baseTy))
8225- conversionsOrFixes.push_back(
8226- ConversionRestrictionKind::StringToPointer);
8227- }
8228- }
8229-
8230- if (type1IsPointer && optionalityMatches &&
8231- (type1PointerKind == PTK_UnsafePointer ||
8232- type1PointerKind == PTK_AutoreleasingUnsafeMutablePointer)) {
8233- conversionsOrFixes.push_back(
8234- ConversionRestrictionKind::PointerToPointer);
8235- }
8229+ if (type1IsPointer && optionalityMatches &&
8230+ (type1PointerKind == PTK_UnsafePointer ||
8231+ type1PointerKind == PTK_AutoreleasingUnsafeMutablePointer)) {
8232+ conversionsOrFixes.push_back(
8233+ ConversionRestrictionKind::PointerToPointer);
82368234 }
8235+ }
82378236
8238- // If both sides are non-optional pointers, let's check whether
8239- // this argument supports Swift -> C pointer conversions.
8240- //
8241- // Do some light verification before recording restriction to
8242- // avoid allocating constraints for obviously invalid cases.
8243- if (type1IsPointer && !type1IsOptional && !type2IsOptional &&
8244- (shouldAttemptFixes() || isArgumentOfImportedDecl(locator))) {
8245- // UnsafeRawPointer -> UnsafePointer<[U]Int8>
8246- if (type1PointerKind == PTK_UnsafeRawPointer &&
8247- pointerKind == PTK_UnsafePointer) {
8248- conversionsOrFixes.push_back(
8249- ConversionRestrictionKind::PointerToCPointer);
8250- }
8237+ // If both sides are non-optional pointers, let's check whether
8238+ // this argument supports Swift -> C pointer conversions.
8239+ //
8240+ // Do some light verification before recording restriction to
8241+ // avoid allocating constraints for obviously invalid cases.
8242+ if (type1IsPointer && !type1IsOptional && !type2IsOptional &&
8243+ (shouldAttemptFixes() || isArgumentOfImportedDecl(locator))) {
8244+ // UnsafeRawPointer -> UnsafePointer<[U]Int8>
8245+ if (type1PointerKind == PTK_UnsafeRawPointer &&
8246+ pointerKind == PTK_UnsafePointer) {
8247+ conversionsOrFixes.push_back(
8248+ ConversionRestrictionKind::PointerToCPointer);
8249+ }
82518250
8252- // UnsafeMutableRawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
8253- if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
8254- (pointerKind == PTK_UnsafePointer ||
8255- pointerKind == PTK_UnsafeMutablePointer)) {
8256- conversionsOrFixes.push_back(
8257- ConversionRestrictionKind::PointerToCPointer);
8258- }
8251+ // UnsafeMutableRawPointer -> Unsafe[Mutable]Pointer<[U]Int8>
8252+ if (type1PointerKind == PTK_UnsafeMutableRawPointer &&
8253+ (pointerKind == PTK_UnsafePointer ||
8254+ pointerKind == PTK_UnsafeMutablePointer)) {
8255+ conversionsOrFixes.push_back(
8256+ ConversionRestrictionKind::PointerToCPointer);
8257+ }
82598258
8260- // Unsafe[Mutable]Pointer -> Unsafe[Mutable]Pointer
8261- if (type1PointerKind == PTK_UnsafePointer &&
8262- pointerKind == PTK_UnsafePointer) {
8263- conversionsOrFixes.push_back(
8264- ConversionRestrictionKind::PointerToCPointer);
8265- }
8259+ // Unsafe[Mutable]Pointer -> Unsafe[Mutable]Pointer
8260+ if (type1PointerKind == PTK_UnsafePointer &&
8261+ pointerKind == PTK_UnsafePointer) {
8262+ conversionsOrFixes.push_back(
8263+ ConversionRestrictionKind::PointerToCPointer);
8264+ }
82668265
8267- if (type1PointerKind == PTK_UnsafeMutablePointer &&
8268- (pointerKind == PTK_UnsafePointer ||
8269- pointerKind == PTK_UnsafeMutablePointer)) {
8270- conversionsOrFixes.push_back(
8271- ConversionRestrictionKind::PointerToCPointer);
8272- }
8266+ if (type1PointerKind == PTK_UnsafeMutablePointer &&
8267+ (pointerKind == PTK_UnsafePointer ||
8268+ pointerKind == PTK_UnsafeMutablePointer)) {
8269+ conversionsOrFixes.push_back(
8270+ ConversionRestrictionKind::PointerToCPointer);
82738271 }
82748272 }
8275- break;
8273+ }
8274+ break;
82768275
8277- case PTK_AutoreleasingUnsafeMutablePointer:
8278- // PTK_AutoreleasingUnsafeMutablePointer can be converted from an
8279- // inout reference to a scalar.
8280- if (!isAutoClosureArgument && type1->is<InOutType>()) {
8281- conversionsOrFixes.push_back(
8282- ConversionRestrictionKind::InoutToPointer);
8283- }
8284- break;
8276+ case PTK_AutoreleasingUnsafeMutablePointer:
8277+ // PTK_AutoreleasingUnsafeMutablePointer can be converted from an
8278+ // inout reference to a scalar.
8279+ if (!isAutoClosureArgument && type1->is<InOutType>()) {
8280+ conversionsOrFixes.push_back(
8281+ ConversionRestrictionKind::InoutToPointer);
82858282 }
8283+ break;
82868284 }
82878285 }
82888286 }
0 commit comments