From a971a0c9802f0dd15ef44b9659c206d82207ed3d Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Thu, 15 Jun 2023 11:08:56 -0700 Subject: [PATCH 1/2] AST: Add convenience for limiting diags to warnings in swiftinterfaces. Sometimes it's useful to be more lenient when type checking swiftinterfaces since restrictions that could be dropped in the future will manifest in resilient libraries being incompatible with older compilers otherwise. --- include/swift/AST/DiagnosticEngine.h | 9 +++++++++ lib/AST/DiagnosticEngine.cpp | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h index df9130b971694..fce04b13d43b7 100644 --- a/include/swift/AST/DiagnosticEngine.h +++ b/include/swift/AST/DiagnosticEngine.h @@ -564,6 +564,15 @@ namespace swift { /// until the next major language version. InFlightDiagnostic &warnUntilSwiftVersion(unsigned majorVersion); + /// Limit the diagnostic behavior to warning if the context is a + /// swiftinterface. + /// + /// This is useful for diagnostics for restrictions that may be lifted by a + /// future version of the compiler. In such cases, it may be helpful to + /// avoid failing to build a module from its interface if the interface was + /// emitted using a compiler that no longer has the restriction. + InFlightDiagnostic &warnInSwiftInterface(const DeclContext *context); + /// Conditionally limit the diagnostic behavior to warning until /// the specified version. If the condition is false, no limit is /// imposed, meaning (presumably) it is treated as an error. diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index ef08ea1fe6eff..f96915d750b68 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -334,6 +334,16 @@ InFlightDiagnostic::warnUntilSwiftVersion(unsigned majorVersion) { return *this; } +InFlightDiagnostic & +InFlightDiagnostic::warnInSwiftInterface(const DeclContext *context) { + auto sourceFile = context->getParentSourceFile(); + if (sourceFile && sourceFile->Kind == SourceFileKind::Interface) { + return limitBehavior(DiagnosticBehavior::Warning); + } + + return *this; +} + InFlightDiagnostic & InFlightDiagnostic::wrapIn(const Diagnostic &wrapper) { // Save current active diagnostic into WrappedDiagnostics, ignoring state From c8f4dabe020380163b38917e22bb58436b9a8f0d Mon Sep 17 00:00:00 2001 From: Allan Shortlidge Date: Wed, 14 Jun 2023 17:06:34 -0700 Subject: [PATCH 2/2] Sema: Diagnose `@backDeployed` on functions with opaque result types. The compiler does not yet implement support for back deploying opaque result types. Resolves rdar://110806234 --- include/swift/AST/DiagnosticsSema.def | 4 ++++ lib/Sema/TypeCheckAttr.cpp | 8 ++++++++ test/attr/attr_backDeployed.swift | 15 +++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 88358f0d2ace7..63cde20ba0480 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7053,6 +7053,10 @@ ERROR(attr_incompatible_with_back_deploy,none, "'%0' cannot be applied to a back deployed %1", (DeclAttribute, DescriptiveDeclKind)) +ERROR(backdeployed_opaque_result_not_supported,none, + "'%0' is unsupported on a %1 with a 'some' return type", + (DeclAttribute, DescriptiveDeclKind)) + //------------------------------------------------------------------------------ // MARK: Implicit opening of existential types //------------------------------------------------------------------------------ diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 4c81fe8540fae..9b21805409618 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -4349,6 +4349,14 @@ void AttributeChecker::checkBackDeployedAttrs( } } + if (VD->getOpaqueResultTypeDecl()) { + diagnoseAndRemoveAttr(Attr, + diag::backdeployed_opaque_result_not_supported, + Attr, D->getDescriptiveKind()) + .warnInSwiftInterface(D->getDeclContext()); + continue; + } + auto AtLoc = Attr->AtLoc; auto Platform = Attr->Platform; diff --git a/test/attr/attr_backDeployed.swift b/test/attr/attr_backDeployed.swift index 5108d537e787e..c7d4d3e0bbf31 100644 --- a/test/attr/attr_backDeployed.swift +++ b/test/attr/attr_backDeployed.swift @@ -261,6 +261,21 @@ protocol CannotBackDeployProtocol {} @backDeployed(before: macOS 12.0) // expected-error {{'@backDeployed' attribute cannot be applied to this declaration}} public actor CannotBackDeployActor {} +public struct ConformsToTopLevelProtocol: TopLevelProtocol { + public init() {} +} + +@available(SwiftStdlib 5.1, *) +@backDeployed(before: macOS 12.0) // expected-error {{'@backDeployed' is unsupported on a var with a 'some' return type}} +public var cannotBackDeployVarWithOpaqueResultType: some TopLevelProtocol { + return ConformsToTopLevelProtocol() +} + +@available(SwiftStdlib 5.1, *) +@backDeployed(before: macOS 12.0) // expected-error {{'@backDeployed' is unsupported on a global function with a 'some' return type}} +public func cannotBackDeployFuncWithOpaqueResultType() -> some TopLevelProtocol { + return ConformsToTopLevelProtocol() +} // MARK: - Function body diagnostics