Skip to content

Treat package as resilient as non-frozen public by default #70141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/AST/AccessScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class AccessScope {
bool isFileScope() const;
bool isInternal() const;
bool isPackage() const;
bool isPublicOrPackage() const { return isPublic() || isPackage(); }

/// Checks if the DeclContext of this (use site) access scope is more
/// restrictive than that of the argument (decl site) based on the DeclContext
Expand Down
6 changes: 3 additions & 3 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2986,7 +2986,7 @@ bool AbstractStorageDecl::isFormallyResilient() const {
// Non-public global and static variables always have a
// fixed layout.
if (!getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true).isPublic())
/*treatUsableFromInlineAsPublic=*/true).isPublicOrPackage())
return false;

return true;
Expand Down Expand Up @@ -4987,10 +4987,10 @@ int TypeDecl::compare(const TypeDecl *type1, const TypeDecl *type2) {
}

bool NominalTypeDecl::isFormallyResilient() const {
// Private, (unversioned) internal, and package types always have a
// Private and (unversioned) internal types always have a
// fixed layout.
if (!getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true).isPublic())
/*treatUsableFromInlineAsPublic=*/true).isPublicOrPackage())
return false;

// Check for an explicit @_fixed_layout or @frozen attribute.
Expand Down
16 changes: 16 additions & 0 deletions test/IRGen/Inputs/package_types/resilient_class.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ package class ResilientGenericOutsideParent<A> {
}
}

public class PublicGenericOutsideParent<A> {
public var property: A
public init(property: A) {
self.property = property
print("PublicGenericOutsideParent.init()")
}

public func method() {
print("PublicGenericOutsideParent.method()")
}

public class func classMethod() {
print("PublicGenericOutsideParent.classMethod()")
}
}


// Resilient generic subclass

Expand Down
22 changes: 22 additions & 0 deletions test/IRGen/Inputs/package_types/resilient_enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ package enum SimpleShape {
case Triangle(Size)
}

public enum PublicSimpleShape {
case pbKleinBottle
case pbTriangle(PublicSize)
}

// Fixed-layout enum with resilient members
package enum Shape {
case Point
Expand All @@ -19,6 +24,11 @@ package enum FunnyShape {
indirect case Trapezoid(Size)
}

public enum PublicFunnyShape {
indirect case Parallelogram(PublicSize)
indirect case Trapezoid(PublicSize)
}

package enum FullyFixedLayout {
case noPayload
case hasPayload(Int)
Expand Down Expand Up @@ -58,6 +68,18 @@ package enum Medium {
case Canvas // 1
}

public enum PublicMedium {
// Indirect case
indirect case Pamphlet(PublicMedium) // -1

// Case with resilient payload
case Postcard(PublicSize) // -2

// Empty cases
case Paper // 0
case Canvas // 1
}

// Indirect resilient enum
package indirect enum IndirectApproach {
case Angle(Double) // -1
Expand Down
66 changes: 63 additions & 3 deletions test/IRGen/Inputs/package_types/resilient_struct.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Fixed-layout struct
package struct Point {
package var x: Int // read-write stored property
package let y: Int // read-only stored property
Expand All @@ -12,7 +11,6 @@ package struct Point {
package mutating func mutantMethod() {}
}

// Resilient-layout struct
package struct Size {
package var w: Int // should have getter and setter
package let h: Int // getter only
Expand All @@ -26,7 +24,6 @@ package struct Size {
package mutating func mutantMethod() {}
}

// Fixed-layout struct with resilient members
package struct Rectangle {
package let p: Point
package let s: Size
Expand Down Expand Up @@ -119,3 +116,66 @@ package struct UnavailableResilientInt {
self.i = i
}
}


public struct PublicPoint {
public var x: Int // read-write stored property
public let y: Int // read-only stored property

public init(x: Int, y: Int) {
self.x = x
self.y = y
}

public func method() {}
public mutating func mutantMethod() {}
}

@frozen
public struct FrozenPublicPoint {
public var x: Int // read-write stored property
public let y: Int // read-only stored property

public init(x: Int, y: Int) {
self.x = x
self.y = y
}

public func method() {}
public mutating func mutantMethod() {}
}

public struct PublicSize {
public var w: Int // should have getter and setter
public let h: Int // getter only

public init(w: Int, h: Int) {
self.w = w
self.h = h
}

public func method() {}
public mutating func mutantMethod() {}
}

@frozen
public struct FrozenPublicSize {
public var w: Int // should have getter and setter
public let h: Int // getter only

public init(w: Int, h: Int) {
self.w = w
self.h = h
}

public func method() {}
public mutating func mutantMethod() {}
}

public struct PublicResilientInt {
public let i: Int

public init(i: Int) {
self.i = i
}
}
2 changes: 2 additions & 0 deletions test/IRGen/package_resilience.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// possible.
//

// REQUIRES: rdar118947451

// RUN: %empty-directory(%t)
// RUN: %{python} %utils/chex.py < %s > %t/package_resilience.swift
// RUN: %target-swift-frontend -package-name MyPkg -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/Inputs/package_types/resilient_struct.swift
Expand Down
Loading