From b9f00ef9236a56ea2aedec1bc2d7d312f7e9fc62 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 19 Sep 2025 16:19:17 -0700 Subject: [PATCH] Warn about the use of internal bridging headers without library evolution It's very, very easy to make a mistake that will cause broken serialized modules. Until that's no longer true, at least tell folks that they are heading into uncharted waters, as we do with `@_implementationOnly` imports. --- include/swift/AST/DiagnosticsFrontend.def | 3 +++ lib/Frontend/CompilerInvocation.cpp | 7 +++++++ .../InternalBridgingHeader/library_evolution.swift | 14 ++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 test/ClangImporter/InternalBridgingHeader/library_evolution.swift diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 754ea7d3780..c2ebf1b73e9 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -609,6 +609,9 @@ ERROR(no_swift_sources_with_embedded,none, ERROR(package_cmo_requires_library_evolution, none, "Library evolution must be enabled for Package CMO", ()) +WARNING(internal_bridging_header_without_library_evolution,none, + "using internal bridging headers without library evolution can cause instability", ()) + ERROR(experimental_not_supported_in_production,none, "experimental feature '%0' cannot be enabled in production compiler", (StringRef)) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 697536b1a93..0f7e155b9c2 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2129,6 +2129,13 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args, Opts.BridgingHeaderIsInternal = importAsInternal; } + // Until we have some checking in place, internal bridging headers are a + // bit unsafe without library evolution. + if (Opts.BridgingHeaderIsInternal && !FrontendOpts.EnableLibraryEvolution) { + Diags.diagnose(SourceLoc(), + diag::internal_bridging_header_without_library_evolution); + } + Opts.DisableSwiftBridgeAttr |= Args.hasArg(OPT_disable_swift_bridge_attr); Opts.DisableOverlayModules |= Args.hasArg(OPT_emit_imported_modules); diff --git a/test/ClangImporter/InternalBridgingHeader/library_evolution.swift b/test/ClangImporter/InternalBridgingHeader/library_evolution.swift new file mode 100644 index 00000000000..df3b9de4bf5 --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/library_evolution.swift @@ -0,0 +1,14 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk %s 2>&1 | %FileCheck -check-prefix NONRESILIENT %s + +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk %s -enable-library-evolution 2>&1 | %FileCheck -check-prefix EVOLUTION %s + +// NONRESILIENT: warning: using internal bridging headers without library evolution can cause instability + +// EVOLUTION-NOT: internal bridging head + +@available(*, deprecated) +func f() { } + +func g(){ + f() // make sure we emit something +}