Skip to content

Commit 25762c2

Browse files
committed
[CSSimplify] Make sure that Swift -> C pointer conversion always waits for optionals
Wait for a value-to-optional promotion or optional-to-optional conversion to happen before attempting Swift -> C pointer conversion.
1 parent de35114 commit 25762c2

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5889,13 +5889,12 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
58895889
}
58905890
}
58915891

5892-
// If both sides are non-optional pointers let's check whether
5892+
// If both sides are non-optional pointers, let's check whether
58935893
// this argument supports Swift -> C pointer conversions.
58945894
//
58955895
// Do some light verification before recording restriction to
58965896
// avoid allocating constraints for obviously invalid cases.
5897-
if (type1IsPointer && optionalityMatches &&
5898-
isArgumentOfImportedDecl(locator)) {
5897+
if (type1IsPointer && !type1IsOptional && !type2IsOptional) {
58995898
// UnsafeRawPointer -> UnsafePointer<[U]Int8>
59005899
if (type1PointerKind == PTK_UnsafeRawPointer &&
59015900
pointerKind == PTK_UnsafePointer) {
@@ -11385,6 +11384,12 @@ ConstraintSystem::SolutionKind
1138511384
ConstraintSystem::simplifyPointerToCPointerRestriction(
1138611385
Type type1, Type type2, TypeMatchOptions flags,
1138711386
ConstraintLocatorBuilder locator) {
11387+
// If this is not an imported function, let's not proceed with this
11388+
// conversion.
11389+
if (!isArgumentOfImportedDecl(locator)) {
11390+
return SolutionKind::Error;
11391+
}
11392+
1138811393
// Make sure that solutions with implicit pointer conversions
1138911394
// are always worse than the ones without them.
1139011395
increaseScore(SK_ImplicitValueConversion);

lib/Sema/ConstraintSystem.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5001,11 +5001,29 @@ bool constraints::isArgumentOfReferenceEqualityOperator(
50015001

50025002
bool ConstraintSystem::isArgumentOfImportedDecl(
50035003
ConstraintLocatorBuilder locator) {
5004-
auto last = locator.last();
5005-
if (!(last && last->is<LocatorPathElt::ApplyArgToParam>()))
5004+
SmallVector<LocatorPathElt, 4> path;
5005+
auto anchor = locator.getLocatorParts(path);
5006+
5007+
if (path.empty())
50065008
return false;
50075009

5008-
auto *application = getCalleeLocator(getConstraintLocator(locator));
5010+
while (!path.empty()) {
5011+
const auto &last = path.back();
5012+
5013+
// Drop all of the `optional payload` or `generic argument`
5014+
// locator elements at the end of the path, they came from
5015+
// either value-to-optional promotion or optional-to-optional
5016+
// conversion.
5017+
if (last.is<LocatorPathElt::OptionalPayload>() ||
5018+
last.is<LocatorPathElt::GenericArgument>()) {
5019+
path.pop_back();
5020+
continue;
5021+
}
5022+
5023+
break;
5024+
}
5025+
5026+
auto *application = getCalleeLocator(getConstraintLocator(anchor, path));
50095027

50105028
auto overload = findSelectedOverloadFor(application);
50115029
if (!(overload && overload->choice.isDecl()))

0 commit comments

Comments
 (0)