Skip to content

SILGen: Ensure Foundation is publicly imported before referencing NSError in code gen #79487

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 2 commits into from
Feb 28, 2025

Conversation

xymus
Copy link
Contributor

@xymus xymus commented Feb 19, 2025

Revisit the optimization that provides a fast path for instances of NSError when erasing the Error type in emitExistentialErasure. It generated references to NSError when the Foundation module was loaded, no matter how it was imported. This lead to deserialization failures at reading the swiftmodule when that reference was added to inlinable code while Foundation was not a public dependency.

Fix this crash by limiting the optimization to all non-inlinable code and only inlinable code from a file with a public dependency on Foundation. This is the similar check we apply to user written inlinable code.

rdar://142438679

@xymus xymus requested a review from jckarter as a code owner February 19, 2025 18:04
@xymus
Copy link
Contributor Author

xymus commented Feb 19, 2025

@swift-ci Please smoke test

@xymus
Copy link
Contributor Author

xymus commented Feb 19, 2025

@jckarter I would appreciate your review here. It would be possible to use the module-wide dependency information if it's preferable at the SIL level. The current use of source file local imports (and the re-exports) may limit this optimization more than necessary.

@nkcsgexi
Copy link
Contributor

Interesting. I'm surprised that we never have had a referenceAllowed function before in SILGen.

@xymus
Copy link
Contributor Author

xymus commented Feb 19, 2025

Me too, however most references to built-ins like this are for stdlib services, in that case the check is less useful in practice. Still I'm open to hear if there's something already in place for this in SILGen or an approach more appropriate to this component.

Revisit the optimization that provides a fast path for instances of
`NSError` when erasing the `Error` type in `emitExistentialErasure`. It
generated references to `NSError` when the `Foundation` module was
loaded, no matter how it was imported. This lead to deserialization
failures at reading the swiftmodule when that reference was added to
inlinable code while `Foundation` was not a public dependency.

Fix this crash by limiting the optimization to all non-inlinable code
and only inlinable code from a module with a public dependency on
`Foundation`. This is the similar check we apply to user written
inlinable code, however here we use the module-wide dependency instead
of per file imports.

rdar://142438679
@xymus xymus force-pushed the limit-nserror-optimization-to-import branch from d75993b to db7126c Compare February 19, 2025 23:35
@xymus
Copy link
Contributor Author

xymus commented Feb 19, 2025

Updated the logic to enable the optimization if there's any public dependency on Foundation at the module level, instead of the file level. Also added a few more test cases.

@swift-ci Please smoke test

@xymus
Copy link
Contributor Author

xymus commented Feb 20, 2025

@swift-ci Please smoke test macOS

@xymus
Copy link
Contributor Author

xymus commented Feb 20, 2025

@swift-ci Please smoke test Linux

@jckarter
Copy link
Contributor

Does the fallback path do the right thing for an opaque NSError-to-Error conversion? If so this looks reasonable.

Ensure that a function manipulating an existential Error still supports
NSError types with or without the fast-path optimization.
@xymus
Copy link
Contributor Author

xymus commented Feb 28, 2025

I added a runtime test to ensure we preserve the expected behavior for an NSError instance with or without the optimization modified here.

@swift-ci Please smoke test

@xymus xymus merged commit e97db1c into swiftlang:main Feb 28, 2025
3 checks passed
@xymus xymus deleted the limit-nserror-optimization-to-import branch February 28, 2025 23:21
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.

3 participants