@@ -281,22 +281,8 @@ swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
281281 }
282282
283283 // Generic requirements are not yet supported in C++.
284- if (genericSignature) {
285-
286- // FIXME: This should use getRequirements() and actually
287- // support arbitrary requirements. We don't really want
288- // to use getRequirementsWithInverses() here.
289- //
290- // For now, we use the inverse transform as a quick way to
291- // check for the "default" generic signature where each
292- // generic parameter is Copyable and Escapable, but not
293- // subject to any other requirements; that's exactly the
294- // generic signature that C++ interop supports today.
295- SmallVector<Requirement, 2 > reqs;
296- SmallVector<InverseRequirement, 2 > inverseReqs;
297- genericSignature->getRequirementsWithInverses (reqs, inverseReqs);
298- if (!reqs.empty () || !inverseReqs.empty ())
299- return {Unsupported, UnrepresentableGenericRequirements};
284+ if (!isExposableToCxx (genericSignature)) {
285+ return {Unsupported, UnrepresentableGenericRequirements};
300286 }
301287
302288 return {Representable, std::nullopt };
@@ -321,6 +307,51 @@ bool swift::cxx_translation::isVisibleToCxx(const ValueDecl *VD,
321307 return false ;
322308}
323309
310+ bool swift::cxx_translation::isExposableToCxx (GenericSignature genericSig) {
311+ // If there's no generic signature, it's fine.
312+ if (!genericSig)
313+ return true ;
314+
315+ // FIXME: This should use getRequirements() and actually
316+ // support arbitrary requirements. We don't really want
317+ // to use getRequirementsWithInverses() here.
318+ //
319+ // For now, we use the inverse transform as a quick way to
320+ // check for the "default" generic signature where each
321+ // generic parameter is Copyable and Escapable, but not
322+ // subject to any other requirements; that's exactly the
323+ // generic signature that C++ interop supports today.
324+ SmallVector<Requirement, 2 > reqs;
325+ SmallVector<InverseRequirement, 2 > inverseReqs;
326+ genericSig->getRequirementsWithInverses (reqs, inverseReqs);
327+ if (!reqs.empty ()) {
328+ // Conformance requirements to marker protocols are okay.
329+ for (const auto &req: reqs) {
330+ if (req.getKind () != RequirementKind::Conformance)
331+ return false ;
332+
333+ auto proto = req.getProtocolDecl ();
334+ if (!proto->isMarkerProtocol ())
335+ return false ;
336+ }
337+ }
338+
339+ // Allow Copyable and Escapable.
340+ for (const auto &req: inverseReqs) {
341+ switch (req.getKind ()) {
342+ case InvertibleProtocolKind::Copyable:
343+ continue ;
344+
345+ case InvertibleProtocolKind::Escapable:
346+ continue ;
347+ }
348+
349+ return false ;
350+ }
351+
352+ return true ;
353+ }
354+
324355Diagnostic
325356swift::cxx_translation::diagnoseRepresenationError (RepresentationError error,
326357 ValueDecl *vd) {
0 commit comments