Skip to content

Commit 279ef7d

Browse files
committed
[CSBindings] Infer bindings through inout in some cases
Allow inferring type of `inout` from a pointer type (or optional thereof) but delay the binding set because it might not be complete and object type of `inout` could also be an Array or C-style pointer type.
1 parent b1d9ae0 commit 279ef7d

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,23 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
14841484
AdjacentVars.insert({typeVar, constraint});
14851485
}
14861486

1487+
// Infer a binding from `inout $T <convertible to> Unsafe*Pointer<...>?`.
1488+
if (first->is<InOutType>() &&
1489+
first->getInOutObjectType()->isEqual(TypeVar)) {
1490+
if (auto pointeeTy = second->lookThroughAllOptionalTypes()
1491+
->getAnyPointerElementType()) {
1492+
if (!pointeeTy->isTypeVariableOrMember()) {
1493+
// The binding is as a fallback in this case because $T could
1494+
// also be Array<X> or C-style pointer.
1495+
if (constraint->getKind() >= ConstraintKind::ArgumentConversion)
1496+
DelayedBy.push_back(constraint);
1497+
1498+
return PotentialBinding(pointeeTy, AllowedBindingKind::Exact,
1499+
constraint);
1500+
}
1501+
}
1502+
}
1503+
14871504
return std::nullopt;
14881505
}
14891506

test/Constraints/valid_pointer_conversions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,21 @@ do {
5151
func rdar68254165(ptr: UnsafeMutablePointer<Int8>) {
5252
_ = String(decodingCString: ptr, as: .utf8) // expected-error {{generic parameter 'Encoding' could not be inferred}}
5353
}
54+
55+
// The base of leading-dot syntax could be inferred through an implicit pointer conversion.
56+
do {
57+
struct S {
58+
static var prop = S()
59+
}
60+
61+
func inference_through_optional(_ ptr: UnsafePointer<S>?) {}
62+
63+
inference_through_optional(&.prop) // Ok
64+
65+
func inference_through_force_unwrap(name: String) {
66+
func test(_: UnsafeMutablePointer<Float>!) {}
67+
68+
var outputs = [String: [Float]]()
69+
test(&outputs[name]!) // Ok
70+
}
71+
}

0 commit comments

Comments
 (0)