Skip to content

Commit 5f41d08

Browse files
authored
Merge pull request swiftlang#76315 from swiftlang/elsh/check-interface-srckind
[PackageInterface] Fix isInterfacePackageEffectivelyPublic.
2 parents 42809af + bd9272c commit 5f41d08

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

lib/AST/Decl.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,18 +4219,27 @@ bool ValueDecl::isUsableFromInline() const {
42194219
}
42204220

42214221
bool ValueDecl::isInterfacePackageEffectivelyPublic() const {
4222-
// If a package decl has a @usableFromInline (or other inlinable)
4223-
// attribute, and is defined in a module built from interface, it
4224-
// can be referenced by another module that imports it even though
4225-
// the defining interface module does not have package-name (such
4226-
// as public or private interface); in such case, the decl is treated
4227-
// as public and access checks in sema are skipped.
4228-
// We might need to add another check here to ensure the interface
4229-
// was part of the same package before the package-name was removed.
4230-
return getFormalAccess() == AccessLevel::Package &&
4231-
isUsableFromInline() &&
4232-
getModuleContext()->getPackageName().empty() &&
4233-
getModuleContext()->isBuiltFromInterface();
4222+
// A package decl with @usableFromInline (or other inlinable
4223+
// attributes) is essentially public, and can be printed in
4224+
// public (or private) interface file without package-name;
4225+
// it can be referenced by another module (without package-name)
4226+
// importing such interface module.
4227+
auto isCandidate = getFormalAccess() == AccessLevel::Package &&
4228+
isUsableFromInline() &&
4229+
getModuleContext()->getPackageName().empty();
4230+
if (!isCandidate)
4231+
return false;
4232+
4233+
// Treat the decl as public (1) if it's contained in an interface
4234+
// file, e.g. when running -typecheck-module-from-interface or
4235+
// -compile-module-from-interface.
4236+
isCandidate = false;
4237+
if (auto srcFile = getDeclContext()->getParentSourceFile()) {
4238+
isCandidate = srcFile->Kind == SourceFileKind::Interface;
4239+
}
4240+
// Or (2) if the decl being referenced in a client file is defined
4241+
// in an interface module.
4242+
return isCandidate || getModuleContext()->isBuiltFromInterface();
42344243
}
42354244

42364245
bool ValueDecl::shouldHideFromEditor() const {
@@ -4512,9 +4521,9 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
45124521
if (!pkg) {
45134522
if (VD->isInterfacePackageEffectivelyPublic())
45144523
return AccessScope::getPublic();
4515-
// Instead of reporting and failing early, return the scope of resultDC to
4516-
// allow continuation (should still non-zero exit later if in script mode)
4517-
return AccessScope(resultDC);
4524+
4525+
// If reached here, should be treated as internal.
4526+
return AccessScope(resultDC->getParentModule());
45184527
} else {
45194528
return AccessScope(pkg);
45204529
}

test/ModuleInterface/package_interface_disable_package_name.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,21 @@
1717

1818
// CHECK-PUBLIC-NOT: -package-name foopkg
1919
// CHECK-PUBLIC-NOT: -package-name barpkg
20+
// CHECK-PUBLIC-NOT: pkgVar
2021
// CHECK-PRIVATE-NOT: -package-name foopkg
2122
// CHECK-PRIVATE-NOT: -package-name barpkg
23+
// CHECK-PRIVATE-NOT: pkgVar
2224
// CHECK-PACKAGE-NOT: -package-name foopkg
2325

2426
// CHECK-PUBLIC: -enable-library-evolution -swift-version 6 -module-name Bar
2527
// CHECK-PRIVATE: -enable-library-evolution -swift-version 6 -module-name Bar
2628
// CHECK-PACKAGE: -enable-library-evolution -swift-version 6 -module-name Bar -package-name barpkg
2729

30+
/// Typechecking interface files (without package-name in non-package interface) should succeed.
31+
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/Bar.swiftinterface
32+
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/Bar.private.swiftinterface -module-name Bar
33+
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/Bar.package.swiftinterface -module-name Bar
34+
2835
/// Verify building modules from non-package interfaces succeeds without the package-name flag.
2936
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
3037
// RUN: %target-swift-frontend -typecheck %t/Use.swift -I %t -verify
@@ -71,8 +78,13 @@
7178
// RUN: %target-swift-frontend -typecheck %t/Use.swift -I %t -package-name barpkg -experimental-package-interface-load -verify
7279

7380
//--- Bar.swift
74-
public struct PubStruct {}
81+
public struct PubStruct {
82+
public var pubVar: Int
83+
package var pkgVar: Int
84+
}
85+
7586
@_spi(bar) public struct SPIStruct {}
87+
7688
package struct PkgStruct {}
7789

7890
@usableFromInline

0 commit comments

Comments
 (0)