From 922c30386d63a0d30e54b75607b12ff806b175ca Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Thu, 31 Jul 2025 16:17:56 +0100 Subject: [PATCH] [cxx-interop] Support conforming to protocols with default assoc types In case the type does not define a type alias with the same name fall back to the default type of the associated type in the protocol. Previously, the compiler crashed. Unfortunately, we are still crashing when we do not find the right conformance. In a follow-up PR I plan to add more graceful handling of the case when the lookup fails. rdar://154098495 --- lib/ClangImporter/ImportDecl.cpp | 9 +++++ .../class/conforms-to-associated-types.swift | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test/Interop/Cxx/class/conforms-to-associated-types.swift diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index b2f91b138f405..1d0a57c6942e3 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -10148,6 +10148,15 @@ static void finishTypeWitnesses( break; } + if (!satisfied && assocType->hasDefaultDefinitionType()) { + auto defaultType = assocType->getDefaultDefinitionType(); + auto subMap = + selfType->getContextSubstitutionMap(assocType->getDeclContext()); + defaultType = defaultType.subst(subMap); + conformance->setTypeWitness(assocType, defaultType, assocType); + satisfied = true; + } + if (!satisfied) { ABORT([&](auto &out) { out << "Cannot look up associated type for imported conformance:\n"; diff --git a/test/Interop/Cxx/class/conforms-to-associated-types.swift b/test/Interop/Cxx/class/conforms-to-associated-types.swift new file mode 100644 index 0000000000000..a54b7a5bf1b9b --- /dev/null +++ b/test/Interop/Cxx/class/conforms-to-associated-types.swift @@ -0,0 +1,37 @@ +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/include) +// RUN: split-file %s %t +// +// RUN: %target-swift-frontend -typecheck -module-name a -cxx-interoperability-mode=default -I %t/include %t/a.swift + +//--- include/module.modulemap +module cxx { + header "header.h" + export * +} + +//--- include/header.h +struct S { + S() {} +} __attribute__((swift_attr("conforms_to:a.P"))); + +struct S2 { + S2() {} + using A = S2; +} __attribute__((swift_attr("conforms_to:a.P"))); + +//--- a.swift +import cxx +public protocol P { + associatedtype A = Int + func foo(_: A) +} +extension P { + func foo(_: A) {} +} +func test(s: S) { + let _ = s.foo(0) +} +func test2(s: S2) { + let _ = s.foo(s) +}