Skip to content
Open
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
21 changes: 17 additions & 4 deletions lib/Sema/ResilienceDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,24 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
D->getFormalAccessScope(/*useDC=*/DC,
/*allowUsableFromInline=*/true);

// Public declarations are OK, even if they're SPI or came from an
// implementation-only import. We'll diagnose exportability violations
// from diagnoseDeclRefExportability().
if (declAccessScope.isPublic())
if (declAccessScope.isPublic()) {
// Diagnose private setters accessed from inlinable functions
if (auto *accessor = dyn_cast<AccessorDecl>(D)) {
if (accessor->getAccessorKind() == AccessorKind::Set) {
auto storage = accessor->getStorage();
if (accessor->getFormalAccess() < storage->getFormalAccess()) {
auto diagID = diag::resilience_decl_unavailable;
Context.Diags.diagnose(loc, diagID, D, accessor->getFormalAccess(),
fragileKind.getSelector());
Context.Diags.diagnose(D, diag::resilience_decl_declared_here, D);
}
}
}
// Public declarations are OK, even if they're SPI or came from an
// implementation-only import. We'll diagnose exportability violations
// from diagnoseDeclRefExportability().
return false;
}

// Dynamic declarations were mistakenly not checked in Swift 4.2.
// Do enforce the restriction even in pre-Swift-5 modes if the module we're
Expand Down
37 changes: 37 additions & 0 deletions test/attr/attr_inlinable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,43 @@ public struct HasInternalSetProperty {
}
}

public struct HasUsableFromInlinePrivateSetProperty {
@usableFromInline private(set) var bytes: UnsafeMutableRawPointer // expected-note 2 {{setter for property 'bytes' is not '@usableFromInline' or public}}
public init() {
self.bytes = UnsafeMutableRawPointer.allocate(byteCount: 1024, alignment: 8)
}
@usableFromInline
func modifyPointer(_ ptr: inout UnsafeMutableRawPointer) {
ptr = UnsafeMutableRawPointer.allocate(byteCount: 1, alignment: 1)
}
@usableFromInline
func readPointer(_ ptr: UnsafeMutableRawPointer) {
_ = ptr
}
// writes should trigger diagnostic
@inlinable
public mutating func writeDirect() {
self.bytes = UnsafeMutableRawPointer.allocate(byteCount: 2048, alignment: 8) // expected-error {{setter for property 'bytes' is private and cannot be referenced from an '@inlinable' function}}
}
@inlinable
public mutating func writeFunc() {
modifyPointer(&self.bytes) // expected-error {{setter for property 'bytes' is private and cannot be referenced from an '@inlinable' function}}
}
// reads should be ok
@inlinable
public func usesBytes() -> UnsafeMutableRawPointer {
_ = self.bytes
}
@inlinable
public func readsViaLoad() -> Int {
return self.bytes.load(as: Int.self)
}
@inlinable
public func readsViaFunc() {
readPointer(self.bytes) // OK
}
}

@usableFromInline protocol P {
typealias T = Int
}
Expand Down