Skip to content

Commit 7679a5a

Browse files
committed
[Diagnostics] Improve the diagnostic for invalid optional pointer conversions for an
autoclosure result type. Skip `ConstraintLocator::OptionalPayload` when checking if we're in an autoclosure context for an inout-to-pointer conversion. This lets us apply the `AllowAutoClosurePointerConversion` constraint fix when the pointer is optional. This resolves rdar://problem/53532404
1 parent 4277f11 commit 7679a5a

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,10 +3080,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
30803080
if (kind >= ConstraintKind::Conversion) {
30813081
// It is never legal to form an autoclosure that results in these
30823082
// implicit conversions to pointer types.
3083-
bool isAutoClosureArgument = false;
3084-
if (auto last = locator.last())
3085-
if (last->getKind() == ConstraintLocator::AutoclosureResult)
3086-
isAutoClosureArgument = true;
3083+
bool isAutoClosureArgument = locator.isAutoclosureResult();
30873084

30883085
// Pointer arguments can be converted from pointer-compatible types.
30893086
if (kind >= ConstraintKind::ArgumentConversion) {

lib/Sema/ConstraintLocator.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,21 @@ class ConstraintLocatorBuilder {
715715
return (getSummaryFlags() & ConstraintLocator::IsFunctionConversion);
716716
}
717717

718+
bool isAutoclosureResult() const {
719+
SmallVector<LocatorPathElt, 4> path;
720+
getLocatorParts(path);
721+
722+
auto last = std::find_if(
723+
path.rbegin(), path.rend(), [](LocatorPathElt &elt) -> bool {
724+
return elt.getKind() != ConstraintLocator::OptionalPayload;
725+
});
726+
727+
if (last != path.rend())
728+
return last->getKind() == ConstraintLocator::AutoclosureResult;
729+
730+
return false;
731+
}
732+
718733
/// Retrieve the base constraint locator, on which this builder's
719734
/// path is based.
720735
ConstraintLocator *getBaseLocator() const {

test/Constraints/invalid_implicit_conversions.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ func test(
99
_ ptr: UnsafePointer<Int>,
1010
_ ptrI8: UnsafePointer<Int8>,
1111
_ ptrU8: UnsafePointer<UInt8>,
12-
_ ptrVoid: UnsafePointer<Void> // expected-warning {{UnsafePointer<Void> has been replaced by UnsafeRawPointer}}
12+
_ ptrVoid: UnsafePointer<Void>, // expected-warning {{UnsafePointer<Void> has been replaced by UnsafeRawPointer}}
13+
_ optPtr: UnsafePointer<Int>?
1314
) {
1415
var i: Int = 0
1516
var a: [Int] = [0]
@@ -23,6 +24,7 @@ func test(
2324
takesAutoclosure(mutRawPtr, &a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafeMutableRawPointer'}}
2425
takesAutoclosure(mutPtr, &a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafeMutablePointer<Int>'}}
2526
takesAutoclosure(ptr, &a) // expected-error {{cannot perform pointer conversion of value of type '[Int]' to autoclosure result type 'UnsafePointer<Int>'}}
27+
takesAutoclosure(optPtr, &i) // expected-error {{cannot perform pointer conversion of value of type 'Int' to autoclosure result type 'UnsafePointer<Int>?'}}
2628

2729
takesAutoclosure(rawPtr, a) // expected-error {{cannot invoke 'takesAutoclosure' with an argument list of type '(UnsafeRawPointer, [Int])'}}
2830
// expected-note@-1 {{expected an argument list of type '(T, @autoclosure () throws -> T)'}}

0 commit comments

Comments
 (0)