Skip to content

Commit 353f060

Browse files
author
Gabor Horvath
committed
[cxx-interop] Fix unavailable generics triggering compilation error
In some cases, the reverse interop generated both a forward declaration and a definition with unavailable attribute in the C++ header. Unfortunately, the kinds of these symbol did not match. The forward declaration was templated while the definition was not. The forward declaration has the correct kind, so this patch extends the printing of unavailable definitions to include the generic arguments. rdar://119835933
1 parent 382a8e7 commit 353f060

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,11 @@ class ModuleWriter {
874874
// Emit an unavailable stub for a Swift type.
875875
if (auto *nmtd = dyn_cast<NominalTypeDecl>(vd)) {
876876
auto representation = cxx_translation::getDeclRepresentation(vd);
877+
if (nmtd->isGeneric()) {
878+
auto genericSignature =
879+
nmtd->getGenericSignature().getCanonicalSignature();
880+
ClangSyntaxPrinter(os).printGenericSignature(genericSignature);
881+
}
877882
os << "class ";
878883
ClangSyntaxPrinter(os).printBaseName(vd);
879884
os << " { } SWIFT_UNAVAILABLE_MSG(\"";

test/Interop/SwiftToCxx/unsupported/unsupported-generics-in-cxx.swift

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,61 @@ public class Class1 {
4747
public var index1: Struct1<UInt32> { .init(rawValue: 123) }
4848
}
4949

50+
public struct GlyphIndex<IntType: FixedWidthInteger & UnsignedInteger> {
51+
private var value: IntType
52+
53+
init(value: IntType) {
54+
self.value = value
55+
}
56+
}
57+
58+
public struct QueryResult<GlyphIndexInt: UnsignedInteger & FixedWidthInteger> {
59+
public var glyphIDs: [GlyphIndex<GlyphIndexInt>]
60+
}
61+
62+
public func makeQueryResult() -> QueryResult<UInt32> { .init(glyphIDs: []) }
63+
5064
// CHECK: supported
5165

5266
// CHECK: class SWIFT_SYMBOL("s:5Decls6Class1C") Class1 : public swift::_impl::RefCountedClass {
5367
// CHECK: 'index1' cannot be printed
5468

69+
// CHECK: namespace Decls SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Decls") {
70+
// CHECK: namespace Decls SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Decls") {
71+
// CHECK: SWIFT_INLINE_THUNK void supportedFunc(const T_0_0& x) noexcept SWIFT_SYMBOL("s:5Decls13supportedFuncyyxlF") {
72+
73+
// CHECK: template<class T_0_0>
74+
// CHECK-NEXT: #ifdef __cpp_concepts
75+
// CHECK-NEXT: requires swift::isUsableInGenericContext<T_0_0>
76+
// CHECK-NEXT: #endif // __cpp_concepts
77+
// CHECK-NEXT: class GlyphIndex { } SWIFT_UNAVAILABLE_MSG("generic requirements for generic struct 'GlyphIndex' can not yet be represented in C++");
78+
79+
// CHECK: class Proto { } SWIFT_UNAVAILABLE_MSG("protocol 'Proto' can not yet be represented in C++");
80+
81+
// CHECK: template<class T_0_0>
82+
// CHECK-NEXT: #ifdef __cpp_concepts
83+
// CHECK-NEXT: requires swift::isUsableInGenericContext<T_0_0>
84+
// CHECK-NEXT: #endif // __cpp_concepts
85+
// CHECK-NEXT: class QueryResult { } SWIFT_UNAVAILABLE_MSG("generic requirements for generic struct 'QueryResult' can not yet be represented in C++");
86+
5587
// CHECK: class Struct1 { } SWIFT_UNAVAILABLE_MSG("generic requirements for generic struct 'Struct1' can not yet be represented in C++");
5688

5789
// CHECK: // Unavailable in C++: Swift global function 'unsupportedFunc(_:)'.
5890

59-
// CHECK: class unsupportedGenericClass { } SWIFT_UNAVAILABLE_MSG("generic generic class 'unsupportedGenericClass' can not yet be exposed to C++");
91+
// CHECK: template<class T_0_0>
92+
// CHECK-NEXT: #ifdef __cpp_concepts
93+
// CHECK-NEXT: requires swift::isUsableInGenericContext<T_0_0>
94+
// CHECK-NEXT: #endif // __cpp_concepts
95+
// CHECK-NEXT: class unsupportedGenericClass { } SWIFT_UNAVAILABLE_MSG("generic generic class 'unsupportedGenericClass' can not yet be exposed to C++");
6096
// CHECK-EMPTY:
97+
// CHECK-NEXT: template<class T_0_0>
98+
// CHECK-NEXT: #ifdef __cpp_concepts
99+
// CHECK-NEXT: requires swift::isUsableInGenericContext<T_0_0>
100+
// CHECK-NEXT: #endif // __cpp_concepts
61101
// CHECK-NEXT: class unsupportedGenericEnum { } SWIFT_UNAVAILABLE_MSG("generic requirements for generic enum 'unsupportedGenericEnum' can not yet be represented in C++");
62102
// CHECK-EMPTY:
103+
// CHECK-NEXT: template<class T_0_0>
104+
// CHECK-NEXT: #ifdef __cpp_concepts
105+
// CHECK-NEXT: requires swift::isUsableInGenericContext<T_0_0>
106+
// CHECK-NEXT: #endif // __cpp_concepts
63107
// CHECK-NEXT: class unsupportedGenericStruct { } SWIFT_UNAVAILABLE_MSG("generic requirements for generic struct 'unsupportedGenericStruct' can not yet be represented in C++");

0 commit comments

Comments
 (0)