Skip to content

[ScanDependency] Do not use public/private swiftinterface in the same package #71857

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
Feb 29, 2024

Conversation

cachemeifyoucan
Copy link
Contributor

When scanning finds a dependency in the same package, do not load public/private swiftinterface since they do not have the package level decl to compile the current module. Always prefer package module (if enabled), or use binary module.

This also does some clean up to sync up the code path between implicit and explicit module finding path.

rdar://122356964

@cachemeifyoucan
Copy link
Contributor Author

@swift-ci please smoke test

if (!pkgPath.empty() && fs.exists(pkgPath))
return pkgPath;
// If in the same package, try return the package interface path.
if (auto packageName = getPackageNameFromInterfacePath(interfacePath, fs)) {
Copy link
Contributor

@elsh elsh Feb 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getPackageInterfacePathIfInSamePackage already checks package name, so return its value if non-null.

Copy link
Contributor Author

@cachemeifyoucan cachemeifyoucan Feb 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that is a different interface file (package vs. public, double verification).

The test failure tells me the current approach doesn't quite work yet because how subInvocation handles package name. I am thinking through all the cases to see if I can find a better solution.

@cachemeifyoucan
Copy link
Contributor Author

Note to reviewer. The current approach doesn't quite work because:
If package A imports a module from package B, package B interface still builds with package name B, even the parent is package A. So the check for if package name is the same as embedded will always return true.

I am thinking if the build should be something like: if the module building has a package name, the dependency will have a package name it is equal or no package name if not equal. That is not the same as the current behavior so I need to think through because on the other hand, we want the diagnostics about mis importing interface in the same package to work (which relies on the package name embedded in swiftmodule, which means the module needs to built with -package-name)

@cachemeifyoucan
Copy link
Contributor Author

After some more thinking, I think the thing that is missing from this approach is that when you build a swift interface file, that action will always have -package-name option, but if it is building a public/private module, we should allow loading non-package interface. If the action is a main module compilation or a package module compilation (?), it should only allow binary module or package interface if within the same package.

@cachemeifyoucan
Copy link
Contributor Author

@swift-ci please smoke test

@@ -31,7 +31,7 @@

// RUN: not %target-swift-frontend -typecheck %t/ClientLoadInterface.swift -package-name libPkg -I %t 2> %t/resultY.output
// RUN: %FileCheck %s -check-prefix CHECK-Y < %t/resultY.output
// CHECK-Y: error: module 'LibInterface' is in package 'libPkg' but was built from a non-package interface; modules of the same package can only be loaded if built from source or package interface: {{.*}}LibInterface.private.swiftinterface
// CHECK-Y: error: no such module 'LibInterface'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the behavior we want. The original diagnostics should still happen here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... this is tricky. The reason for the diagnostics do not happen is after the change, the private swiftinterface is not considered a valid dependency for the source, thus it is not doing an implicit module build to create a module that cannot be imported with the error.

You can still construct a case that trigger the warning but you have to produce the wrong module first before running the implicit build. That behavior is verified in test/Sema/accessibility_package_import_interface.swift

@cachemeifyoucan
Copy link
Contributor Author

@swift-ci please smoke test macOS platform

Copy link
Contributor

@xymus xymus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


file_types::ID InputType =
file_types::lookupTypeFromFilename(getFilenameOfFirstInput());
return InputType == file_types::TY_SwiftModuleInterfaceFile ||
Copy link
Contributor

@elsh elsh Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are these input types specified? In deps.json as in the test below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the type of the input on the command-line, determined by file extension. The only time something can import public/private interface when in the same package is building a public/private interface from the same package, hence checking the input type.

… package

When scanning finds a dependency in the same package, do not load
public/private swiftinterface since they do not have the package level
decl to compile the current module. Always prefer package module (if
enabled), or use binary module, unless it is building a public/private
swiftinterface file in which case the interface file is preferred.

This also does some clean up to sync up the code path between implicit
and explicit module finding path.

rdar://122356964
@cachemeifyoucan
Copy link
Contributor Author

@swift-ci please smoke test

@cachemeifyoucan cachemeifyoucan merged commit 244717b into swiftlang:main Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants