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/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/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 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