Skip to content

Commit 34b6241

Browse files
committed
[Diagnostics] Move fix creation of AllowAutoClosurePointerConversion from
`matchTypes` to `repairFailures`. This change handles invalid inout-to-pointer, array-to-pointer, and string- to-pointer autoclosure conversions in the same way.
1 parent 04f09d0 commit 34b6241

File tree

4 files changed

+21
-31
lines changed

4 files changed

+21
-31
lines changed

lib/Sema/CSFix.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,6 @@ enum class FixKind : uint8_t {
9898
/// Swift version 5.
9999
AutoClosureForwarding,
100100

101-
/// Allow invalid pointer conversions for autoclosure result types as if the
102-
/// pointer type is a function parameter rather than an autoclosure result.
103-
AllowAutoClosurePointerConversion,
104-
105101
/// Remove `!` or `?` because base is not an optional type.
106102
RemoveUnwrap,
107103

@@ -627,11 +623,12 @@ class AutoClosureForwarding final : public ConstraintFix {
627623
ConstraintLocator *locator);
628624
};
629625

626+
/// Allow invalid pointer conversions for autoclosure result types as if the
627+
/// pointer type is a function parameter rather than an autoclosure result.
630628
class AllowAutoClosurePointerConversion final : public ContextualMismatch {
631629
AllowAutoClosurePointerConversion(ConstraintSystem &cs, Type pointeeType,
632630
Type pointerType, ConstraintLocator *locator)
633-
: ContextualMismatch(cs, FixKind::AllowAutoClosurePointerConversion,
634-
pointeeType, pointerType, locator) {}
631+
: ContextualMismatch(cs, pointeeType, pointerType, locator) {}
635632

636633
public:
637634
std::string getName() const override {

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,6 +2488,14 @@ bool ConstraintSystem::repairFailures(
24882488
case ConstraintLocator::AutoclosureResult: {
24892489
if (repairByInsertingExplicitCall(lhs, rhs))
24902490
return true;
2491+
2492+
auto result = matchTypes(lhs, rhs, ConstraintKind::ArgumentConversion,
2493+
TypeMatchFlags::TMF_ApplyingFix,
2494+
locator.withPathElement(ConstraintLocator::FunctionArgument));
2495+
2496+
if (result.isSuccess())
2497+
conversionsOrFixes.push_back(AllowAutoClosurePointerConversion::create(
2498+
*this, lhs, rhs, getConstraintLocator(locator)));
24912499
break;
24922500
}
24932501

@@ -3116,11 +3124,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
31163124
}
31173125
conversionsOrFixes.push_back(
31183126
ConversionRestrictionKind::InoutToPointer);
3119-
} else {
3120-
Type pointeeType = inoutType1->getObjectType();
3121-
auto *fix = AllowAutoClosurePointerConversion::create(*this,
3122-
pointeeType, type2, getConstraintLocator(locator));
3123-
conversionsOrFixes.push_back(fix);
31243127
}
31253128
}
31263129

@@ -7010,13 +7013,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
70107013
return matchTupleTypes(matchingType, smaller, matchKind, subflags, locator);
70117014
}
70127015

7013-
case FixKind::AllowAutoClosurePointerConversion: {
7014-
if (recordFix(fix))
7015-
return SolutionKind::Error;
7016-
return matchTypes(type1, type2, matchKind, subflags,
7017-
locator.withPathElement(ConstraintLocator::FunctionArgument));
7018-
}
7019-
70207016
case FixKind::InsertCall:
70217017
case FixKind::RemoveReturn:
70227018
case FixKind::AddConformance:

lib/Sema/ConstraintLocator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,8 @@ class ConstraintLocatorBuilder {
721721

722722
auto last = std::find_if(
723723
path.rbegin(), path.rend(), [](LocatorPathElt &elt) -> bool {
724-
return elt.getKind() != ConstraintLocator::OptionalPayload;
724+
return elt.getKind() != ConstraintLocator::OptionalPayload &&
725+
elt.getKind() != ConstraintLocator::GenericArgument;
725726
});
726727

727728
if (last != path.rend())

test/Constraints/invalid_implicit_conversions.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ func test(
1414
) {
1515
var i: Int = 0
1616
var a: [Int] = [0]
17+
var b: [Int]? = [0]
1718
let s = "string"
1819

1920
takesAutoclosure(rawPtr, &i) // expected-error {{cannot perform pointer conversion of value of type 'Int' to autoclosure result type 'UnsafeRawPointer'}}
@@ -26,17 +27,12 @@ func test(
2627
takesAutoclosure(ptr, &a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafePointer<Int>'}}
2728
takesAutoclosure(optPtr, &i) // expected-error {{cannot perform pointer conversion of value of type 'Int' to autoclosure result type 'UnsafePointer<Int>?'}}
2829

29-
takesAutoclosure(rawPtr, a) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafeRawPointer, [Int])'}}
30-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
31-
takesAutoclosure(ptr, a) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafePointer<Int>, [Int])'}}
32-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
30+
takesAutoclosure(rawPtr, a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafeRawPointer'}}
31+
takesAutoclosure(ptr, a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafePointer<Int>'}}
32+
takesAutoclosure(optPtr, b) // expected-error {{cannot perform pointer conversion of value of type '[Int]?' to autoclosure result type 'UnsafePointer<Int>?'}}
3333

34-
takesAutoclosure(rawPtr, s) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafeRawPointer, String)'}}
35-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
36-
takesAutoclosure(ptrI8, s) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafePointer<Int8>, String)'}}
37-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
38-
takesAutoclosure(ptrU8, s) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafePointer<UInt8>, String)'}}
39-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
40-
takesAutoclosure(ptrVoid, s) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafePointer<Void>, String)'}}
41-
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}
34+
takesAutoclosure(rawPtr, s) // expected-error {{cannot perform pointer conversion of value of type 'String' to autoclosure result type 'UnsafeRawPointer'}}
35+
takesAutoclosure(ptrI8, s) // expected-error {{cannot perform pointer conversion of value of type 'String' to autoclosure result type 'UnsafePointer<Int8>'}}
36+
takesAutoclosure(ptrU8, s) // expected-error {{cannot perform pointer conversion of value of type 'String' to autoclosure result type 'UnsafePointer<UInt8>'}}
37+
takesAutoclosure(ptrVoid, s) // expected-error {{cannot perform pointer conversion of value of type 'String' to autoclosure result type 'UnsafePointer<Void>'}}
4238
}

0 commit comments

Comments
 (0)