mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #79655 from DougGregor/se-0458-condfails
[SE-0458] Improve backward compatibility of generated Swift interfaces
This commit is contained in:
@@ -2901,14 +2901,12 @@ void PrintAST::printInherited(const Decl *decl) {
|
|||||||
Printer << "@preconcurrency ";
|
Printer << "@preconcurrency ";
|
||||||
switch (inherited.getExplicitSafety()) {
|
switch (inherited.getExplicitSafety()) {
|
||||||
case ExplicitSafety::Unspecified:
|
case ExplicitSafety::Unspecified:
|
||||||
break;
|
|
||||||
|
|
||||||
case ExplicitSafety::Safe:
|
case ExplicitSafety::Safe:
|
||||||
Printer << "@safe ";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ExplicitSafety::Unsafe:
|
case ExplicitSafety::Unsafe:
|
||||||
Printer << "@unsafe ";
|
if (!llvm::is_contained(Options.ExcludeAttrList, TypeAttrKind::Unsafe))
|
||||||
|
Printer << "@unsafe ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (inherited.isSuppressed())
|
if (inherited.isSuppressed())
|
||||||
@@ -3218,6 +3216,12 @@ suppressingFeatureMemorySafetyAttributes(PrintOptions &options,
|
|||||||
llvm::function_ref<void()> action) {
|
llvm::function_ref<void()> action) {
|
||||||
ExcludeAttrRAII scope(options.ExcludeAttrList, DeclAttrKind::Unsafe);
|
ExcludeAttrRAII scope(options.ExcludeAttrList, DeclAttrKind::Unsafe);
|
||||||
ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::Safe);
|
ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::Safe);
|
||||||
|
options.ExcludeAttrList.push_back(TypeAttrKind::Unsafe);
|
||||||
|
SWIFT_DEFER {
|
||||||
|
assert(options.ExcludeAttrList.back() == TypeAttrKind::Unsafe);
|
||||||
|
options.ExcludeAttrList.pop_back();
|
||||||
|
};
|
||||||
|
|
||||||
action();
|
action();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "swift/AST/NameLookup.h"
|
#include "swift/AST/NameLookup.h"
|
||||||
#include "swift/AST/ParameterList.h"
|
#include "swift/AST/ParameterList.h"
|
||||||
#include "swift/AST/Pattern.h"
|
#include "swift/AST/Pattern.h"
|
||||||
|
#include "swift/AST/ProtocolConformance.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
#include "swift/Basic/Assertions.h"
|
#include "swift/Basic/Assertions.h"
|
||||||
|
|
||||||
@@ -350,8 +351,32 @@ static bool usesFeatureIsolatedConformances(Decl *decl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool usesFeatureMemorySafetyAttributes(Decl *decl) {
|
static bool usesFeatureMemorySafetyAttributes(Decl *decl) {
|
||||||
return decl->getAttrs().hasAttribute<SafeAttr>() ||
|
if (decl->getAttrs().hasAttribute<SafeAttr>() ||
|
||||||
decl->getAttrs().hasAttribute<UnsafeAttr>();
|
decl->getAttrs().hasAttribute<UnsafeAttr>())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
IterableDeclContext *idc;
|
||||||
|
if (auto nominal = dyn_cast<NominalTypeDecl>(decl))
|
||||||
|
idc = nominal;
|
||||||
|
else if (auto ext = dyn_cast<ExtensionDecl>(decl))
|
||||||
|
idc = ext;
|
||||||
|
else
|
||||||
|
idc = nullptr;
|
||||||
|
|
||||||
|
// Look for an @unsafe conformance ascribed to this declaration.
|
||||||
|
if (idc) {
|
||||||
|
auto conformances = idc->getLocalConformances();
|
||||||
|
for (auto conformance : conformances) {
|
||||||
|
auto rootConformance = conformance->getRootConformance();
|
||||||
|
if (auto rootNormalConformance =
|
||||||
|
dyn_cast<NormalProtocolConformance>(rootConformance)) {
|
||||||
|
if (rootNormalConformance->getExplicitSafety() == ExplicitSafety::Unsafe)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNINTERESTING_FEATURE(StrictMemorySafety)
|
UNINTERESTING_FEATURE(StrictMemorySafety)
|
||||||
|
|||||||
@@ -552,6 +552,10 @@ fileprivate class RemoveUnsafeExprSyntaxRewriter: SyntaxRewriter {
|
|||||||
override func visit(_ node: UnsafeExprSyntax) -> ExprSyntax {
|
override func visit(_ node: UnsafeExprSyntax) -> ExprSyntax {
|
||||||
return node.expression.with(\.leadingTrivia, node.leadingTrivia)
|
return node.expression.with(\.leadingTrivia, node.leadingTrivia)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func visit(_ node: ForStmtSyntax) -> StmtSyntax {
|
||||||
|
return StmtSyntax(node.with(\.unsafeKeyword, nil))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SyntaxProtocol {
|
extension SyntaxProtocol {
|
||||||
|
|||||||
@@ -9,10 +9,21 @@
|
|||||||
// CHECK: #endif
|
// CHECK: #endif
|
||||||
@unsafe public func getIntUnsafely() -> Int { 0 }
|
@unsafe public func getIntUnsafely() -> Int { 0 }
|
||||||
|
|
||||||
|
public struct UnsafeIterator: @unsafe IteratorProtocol {
|
||||||
|
@unsafe public mutating func next() -> Int? { nil }
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SequenceWithUnsafeIterator: Sequence {
|
||||||
|
public init() { }
|
||||||
|
public func makeIterator() -> UnsafeIterator { UnsafeIterator() }
|
||||||
|
}
|
||||||
|
|
||||||
// CHECK: @inlinable public func useUnsafeCode()
|
// CHECK: @inlinable public func useUnsafeCode()
|
||||||
@inlinable public func useUnsafeCode() {
|
@inlinable public func useUnsafeCode() {
|
||||||
// CHECK-NOT: unsafe
|
// CHECK-NOT: unsafe
|
||||||
print( unsafe getIntUnsafely())
|
print( unsafe getIntUnsafely())
|
||||||
|
|
||||||
|
for unsafe _ in SequenceWithUnsafeIterator() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: public protocol P
|
// CHECK: public protocol P
|
||||||
@@ -20,11 +31,12 @@ public protocol P {
|
|||||||
func f()
|
func f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: #if compiler(>=5.3) && $MemorySafetyAttributes
|
||||||
// CHECK: public struct X : @unsafe UserModule.P
|
// CHECK: public struct X : @unsafe UserModule.P
|
||||||
public struct X: @unsafe P {
|
public struct X: @unsafe P {
|
||||||
// CHECK: #if compiler(>=5.3) && $MemorySafetyAttributes
|
|
||||||
// CHECK: @unsafe public func f()
|
// CHECK: @unsafe public func f()
|
||||||
// CHECK: #else
|
// CHECK: #else
|
||||||
|
// CHECK: public struct X : UserModule.P
|
||||||
// CHECK: public func f()
|
// CHECK: public func f()
|
||||||
// CHECK: #endif
|
// CHECK: #endif
|
||||||
@unsafe public func f() { }
|
@unsafe public func f() { }
|
||||||
|
|||||||
Reference in New Issue
Block a user