Skip to content

Commit e7ad1f4

Browse files
authored
Merge pull request #63970 from hyp/eng/unsupported-generics-in-cxx
[interop][SwiftToCxx] diagnose when certain generic decls can not yet…
2 parents ed8aa96 + 8bce678 commit e7ad1f4

File tree

6 files changed

+66
-2
lines changed

6 files changed

+66
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,10 @@ ERROR(expose_unsupported_actor_isolated_to_cxx,none,
16151615
"actor-isolated %0 %1 can not be exposed to C++", (DescriptiveDeclKind, ValueDecl *))
16161616
ERROR(expose_unsupported_client_emission_to_cxx,none,
16171617
"%0 %1 can not be exposed to C++ as it requires code to be emitted into client", (DescriptiveDeclKind, ValueDecl *))
1618+
ERROR(expose_generic_decl_to_cxx,none,
1619+
"generic %0 %1 can not yet be exposed to C++", (DescriptiveDeclKind, ValueDecl *))
1620+
ERROR(expose_generic_requirement_to_cxx,none,
1621+
"generic requirements for %0 %1 can not yet be represented in C++", (DescriptiveDeclKind, ValueDecl *))
16181622

16191623
ERROR(attr_methods_only,none,
16201624
"only methods can be declared %0", (DeclAttribute))

include/swift/AST/SwiftNameTranslation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ enum RepresentationError {
6969
UnrepresentableAsync,
7070
UnrepresentableIsolatedInActor,
7171
UnrepresentableRequiresClientEmission,
72+
UnrepresentableGeneric,
73+
UnrepresentableGenericRequirements
7274
};
7375

7476
struct DeclRepresentation {

lib/AST/SwiftNameTranslation.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,28 @@ swift::cxx_translation::DeclRepresentation
175175
swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
176176
if (getActorIsolation(const_cast<ValueDecl *>(VD)).isActorIsolated())
177177
return {Unsupported, UnrepresentableIsolatedInActor};
178+
Optional<CanGenericSignature> genericSignature;
178179
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD)) {
179180
if (AFD->hasAsync())
180181
return {Unsupported, UnrepresentableAsync};
181182
// Don't expose @_alwaysEmitIntoClient functions as they require their
182183
// bodies to be emitted into client.
183184
if (AFD->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
184185
return {Unsupported, UnrepresentableRequiresClientEmission};
186+
if (AFD->isGeneric())
187+
genericSignature = AFD->getGenericSignature().getCanonicalSignature();
185188
}
189+
if (const auto *typeDecl = dyn_cast<NominalTypeDecl>(VD)) {
190+
if (typeDecl->isGeneric()) {
191+
if (isa<ClassDecl>(VD))
192+
return {Unsupported, UnrepresentableGeneric};
193+
genericSignature =
194+
typeDecl->getGenericSignature().getCanonicalSignature();
195+
}
196+
}
197+
// Generic requirements are not yet supported in C++.
198+
if (genericSignature && !genericSignature->getRequirements().empty())
199+
return {Unsupported, UnrepresentableGenericRequirements};
186200
return {Representable, llvm::None};
187201
}
188202

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
194194
if (typeDecl->isGeneric()) {
195195
genericSignature = typeDecl->getGenericSignature().getCanonicalSignature();
196196
// FIXME: Support generic requirements.
197-
if (!genericSignature->getRequirements().empty())
198-
return;
197+
assert(genericSignature->getRequirements().empty());
199198
// FIXME: Can we make some better layout than opaque layout for generic
200199
// types.
201200
} else if (!typeDecl->isResilient()) {

lib/Sema/TypeCheckAttr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,14 @@ void AttributeChecker::visitExposeAttr(ExposeAttr *attr) {
20092009
diag::expose_unsupported_client_emission_to_cxx,
20102010
VD->getDescriptiveKind(), VD);
20112011
break;
2012+
case UnrepresentableGeneric:
2013+
diagnose(attr->getLocation(), diag::expose_generic_decl_to_cxx,
2014+
VD->getDescriptiveKind(), VD);
2015+
break;
2016+
case UnrepresentableGenericRequirements:
2017+
diagnose(attr->getLocation(), diag::expose_generic_requirement_to_cxx,
2018+
VD->getDescriptiveKind(), VD);
2019+
break;
20122020
}
20132021
}
20142022

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Decls -verify -clang-header-expose-decls=has-expose-attr -disable-availability-checking -emit-clang-header-path %t/decls.h
3+
4+
// RUN: cat %s | grep -v _expose > %t/clean.swift
5+
// RUN: %target-swift-frontend %t/clean.swift -typecheck -module-name Decls -clang-header-expose-decls=all-public -disable-availability-checking -emit-clang-header-path %t/decls.h
6+
// RUN: %FileCheck %s < %t/decls.h
7+
8+
// CHECK-NOT: unsupported
9+
// CHECK: supported
10+
11+
public protocol Proto { init() }
12+
13+
@_expose(Cxx)
14+
public func supportedFunc<T>(_ x: T) {}
15+
16+
@_expose(Cxx) // expected-error {{generic requirements for global function 'unsupportedFunc' can not yet be represented in C++}}
17+
public func unsupportedFunc<T: Proto>(_ x: T) {}
18+
19+
@_expose(Cxx) // expected-error {{generic generic class 'unsupportedGenericClass' can not yet be exposed to C++}}
20+
public class unsupportedGenericClass<T> {
21+
var v: T?
22+
23+
public init() {
24+
v = nil
25+
}
26+
}
27+
28+
@_expose(Cxx) // expected-error {{generic requirements for generic struct 'unsupportedGenericStruct' can not yet be represented in C++}}
29+
public struct unsupportedGenericStruct<T: Proto> {
30+
var v: T
31+
}
32+
33+
@_expose(Cxx) // expected-error {{generic requirements for generic enum 'unsupportedGenericEnum' can not yet be represented in C++}}
34+
public enum unsupportedGenericEnum<T: Proto> {
35+
case A
36+
case B(T)
37+
}

0 commit comments

Comments
 (0)