Skip to content

Commit b8fd75d

Browse files
committed
[cxx-interop] Correctly check iterator conformances
To determine whether to conform a C++ type to `CxxSequence` protocol automatically, ClangImporter checks if the corresponding iterator type conforms to `UnsafeCxxInputIterator`. This logic had false-positives, e.g. `Optional<OpaquePointer>` was treated as if it conforms to `UnsafeCxxInputIterator` while it actually doesn't. This happened because `lookupConformance` returned a conformance with a conditional requirement (`Wrapped : UnsafeCxxInputIterator`) that is not satisfied for `OpaquePointer`. rdar://100265664
1 parent e51f1ff commit b8fd75d

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

lib/ClangImporter/ClangDerivedConformances.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ void swift::conformToCxxSequenceIfNeeded(
228228
return;
229229

230230
// Check if RawIterator conforms to UnsafeCxxInputIterator.
231-
auto rawIteratorConformanceRef = decl->getModuleContext()->lookupConformance(
231+
auto rawIteratorConformanceRef = decl->getModuleContext()->conformsToProtocol(
232232
rawIteratorTy, cxxIteratorProto);
233-
if (!rawIteratorConformanceRef.isConcrete())
233+
if (!rawIteratorConformanceRef || !rawIteratorConformanceRef.isConcrete())
234234
return;
235235
auto rawIteratorConformance = rawIteratorConformanceRef.getConcrete();
236236
auto pointeeDecl =

test/Interop/Cxx/stdlib/overlay/Inputs/custom-sequence.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,16 @@ struct HasBeginEndReturnRef {
8686
const ConstIterator &end() const { return e; }
8787
};
8888

89+
template <typename A> struct NoDefinition;
90+
91+
template <typename A, typename NoDef = NoDefinition<A>>
92+
struct HasTemplatedIterator {
93+
typedef NoDef* iterator; // OpaquePointer
94+
95+
iterator begin() const;
96+
iterator end() const;
97+
};
98+
99+
typedef HasTemplatedIterator<int> HasUninstantiatableIterator;
100+
89101
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_SEQUENCE_H

test/Interop/Cxx/stdlib/overlay/custom-sequence-module-interface.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,9 @@
5858
// CHECK-NOT: typealias Iterator
5959
// CHECK-NOT: typealias RawIterator
6060
// CHECK: }
61+
// CHECK: struct __CxxTemplateInst20HasTemplatedIteratorIi12NoDefinitionIiEE {
62+
// CHECK-NOT: typealias Element
63+
// CHECK-NOT: typealias Iterator
64+
// CHECK-NOT: typealias RawIterator
65+
// CHECK: }
66+
// CHECK: typealias HasUninstantiatableIterator = __CxxTemplateInst20HasTemplatedIteratorIi12NoDefinitionIiEE

0 commit comments

Comments
 (0)