Skip to content

Commit ff696c4

Browse files
authored
Merge pull request #66155 from apple/es-crash
Fix a crash during lookup of an operator with package acl
2 parents 47d3b18 + 7b27997 commit ff696c4

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

lib/AST/Decl.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3973,10 +3973,12 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
39733973
auto pkg = resultDC->getPackageContext(/*lookupIfNotCurrent*/ true);
39743974
if (!pkg) {
39753975
auto srcFile = resultDC->getParentSourceFile();
3976-
// Check if the file containing package decls is an interface file; if a public
3977-
// interface contains package decls, they must be inlinable and do not need a
3978-
// package-name, so don't show diagnostics in that case.
3979-
if (srcFile && srcFile->Kind != SourceFileKind::Interface) {
3976+
// Check if the file containing package decls is an interface file; if an
3977+
// interface file contains package decls, they must be usableFromInline or
3978+
// inlinable and are accessed within the defining module, so package-name
3979+
// is not needed; do not show diagnostics in such case.
3980+
auto shouldSkipDiag = srcFile && srcFile->Kind == SourceFileKind::Interface;
3981+
if (!shouldSkipDiag) {
39803982
// No package context was found; show diagnostics
39813983
auto &d = VD->getASTContext().Diags;
39823984
d.diagnose(VD->getLoc(), diag::access_control_requires_package_name);
@@ -4175,15 +4177,16 @@ static bool checkAccess(const DeclContext *useDC, const ValueDecl *VD,
41754177
}
41764178
case AccessLevel::Package: {
41774179
auto srcFile = sourceDC->getParentSourceFile();
4178-
if (srcFile && srcFile->Kind != SourceFileKind::Interface) {
4179-
auto srcPkg = sourceDC->getPackageContext(/*lookupIfNotCurrent*/ true);
4180-
auto usePkg = useDC->getPackageContext(/*lookupIfNotCurrent*/ true);
4181-
return usePkg->isSamePackageAs(srcPkg);
4182-
} else {
4183-
// If source file is interface, package decls must be inlinable,
4184-
// essentially treated public so return true (see AccessLevel::Public)
4180+
4181+
// srcFile could be null if VD decl is from an imported .swiftmodule
4182+
if (srcFile && srcFile->Kind == SourceFileKind::Interface) {
4183+
// If source file is interface, package decls must be usableFromInline or
4184+
// inlinable, and are accessed only within the defining module so return true
41854185
return true;
41864186
}
4187+
auto srcPkg = sourceDC->getPackageContext(/*lookupIfNotCurrent*/ true);
4188+
auto usePkg = useDC->getPackageContext(/*lookupIfNotCurrent*/ true);
4189+
return srcPkg && usePkg && usePkg->isSamePackageAs(srcPkg);
41874190
}
41884191
case AccessLevel::Public:
41894192
case AccessLevel::Open:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -verify -module-name Lib %t/Lib.swift -emit-module -emit-module-path %t/Lib.swiftmodule -package-name myPkg
5+
6+
/// Type-checking an operator (L30 below) causes look up of all of its decls regardless of which access modifier is
7+
/// used (decl in both Client and Lib in this case) before filtering. The decl in Lib is a package decl and has
8+
/// package-name associated with it, but the use site (in Client) does not have package-name. The package decl
9+
/// should be filtered out and the public == decl should be picked.
10+
// RUN: %target-swift-frontend -typecheck -verify %t/Client.swift -I %t
11+
12+
13+
//--- Lib.swift
14+
public class Decl {
15+
package static func == (lhs: Decl, rhs: Decl) -> Bool {
16+
return true
17+
}
18+
}
19+
20+
//--- Client.swift
21+
import Lib
22+
23+
extension Decl: Equatable {
24+
public static func == (lhs: Decl, rhs: Decl) -> Bool {
25+
return false
26+
}
27+
}
28+
29+
public protocol Proto {}
30+
extension Proto {
31+
func foo(first: Decl, second: Decl) -> Bool {
32+
// Type-checking below causes a look up of == in both Client and Lib
33+
return first == second
34+
}
35+
}

0 commit comments

Comments
 (0)