Skip to content

Conversation

@QuietMisdreavus
Copy link
Contributor

Resolves rdar://152598492

Consider the following Swift, adapted from a real-world framework:

@available(macOS 10.8, *)
@_originallyDefinedIn(module: "another", macOS 11.0)
public struct SimpleStruct {}

@available(macOS 12.0, iOS 13.0, *)
public extension SimpleStruct {
    struct InnerStruct {}
}

In this scenario, SimpleStruct was originally in a module called another, but was migrated to this module around the time of macOS 11.0. Since then, the module was ported to iOS and gained a nested type SimpleStruct.InnerStruct. When mangling USRs for this nested type, the result differs depending on whether we're targeting macOS or iOS. They're mostly the same, but the macOS build yields a USR with an AAE infix, designating that the InnerStruct was defined in an extension from a module with the name of the base module. On iOS, this infix does not exist.

The reason this is happening is because of the implementation of getAlternateModuleName checking the availability spec in the @_originallyDefinedIn attribute against the currently active target. If the target matches the spec, then the alternate module name is reported, otherwise the real module name is. Since the iOS build reports the real module name, the mangling code doesn't bother including the extension-context infix, instead just opting to include the parent type's name and moving on.

This PR routes around this issue by passing the RespectOriginallyDefinedIn variable to the ExtensionDecl::isInSameDefiningModule method, and using that to skip the alternate module name entirely. It also sets RespectOriginallyDefinedIn to false in more places when mangling USRs, but i'm not 100% confident that it was all necessary. The goal was to make USRs more consistent across platforms, regardless of the surrounding context.

@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please test

@QuietMisdreavus
Copy link
Contributor Author

@etcwilde @edymtt This is the PR with the lit updates i was talking about. I wanted to expose SWIFT_SDKS at a minimum so i could know that i could target code for the iOS simulator. The test is specifically wanting to compare builds targeting two different platforms, and i wanted to make sure that i could verify that that was possible before doing that in a lit context.

Copy link
Contributor

@edymtt edymtt left a comment

Choose a reason for hiding this comment

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

LGTM for the lit.cfg changes

@QuietMisdreavus QuietMisdreavus requested a review from nkcsgexi June 18, 2025 19:09
@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please test macOS

@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please clean test macOS

1 similar comment
@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please clean test macOS

@QuietMisdreavus QuietMisdreavus force-pushed the vgm/alternate-module-usr branch from f4385de to 5e3e9d6 Compare June 26, 2025 21:39
@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please clean test macOS

@QuietMisdreavus QuietMisdreavus force-pushed the vgm/alternate-module-usr branch from 5e3e9d6 to de80e21 Compare June 26, 2025 22:13
@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please test

1 similar comment
@QuietMisdreavus
Copy link
Contributor Author

@swift-ci Please test

@QuietMisdreavus QuietMisdreavus merged commit 1948907 into main Jun 30, 2025
5 checks passed
@QuietMisdreavus QuietMisdreavus deleted the vgm/alternate-module-usr branch June 30, 2025 18:57
QuietMisdreavus added a commit that referenced this pull request Jun 30, 2025
Resolves rdar://152598492

Consider the following Swift, adapted from a real-world framework:

```swift
@available(macOS 10.8, *)
@_originallyDefinedIn(module: "another", macOS 11.0)
public struct SimpleStruct {}

@available(macOS 12.0, iOS 13.0, *)
public extension SimpleStruct {
    struct InnerStruct {}
}
```

In this scenario, `SimpleStruct` was originally in a module called
`another`, but was migrated to this module around the time of macOS
11.0. Since then, the module was ported to iOS and gained a nested type
`SimpleStruct.InnerStruct`. When mangling USRs for this nested type, the
result differs depending on whether we're targeting macOS or iOS.
They're mostly the same, but the macOS build yields a USR with an `AAE`
infix, designating that the `InnerStruct` was defined in an extension
from a module with the name of the base module. On iOS, this infix does
not exist.

The reason this is happening is because of the implementation of
`getAlternateModuleName` checking the availability spec in the
`@_originallyDefinedIn` attribute against the currently active target.
If the target matches the spec, then the alternate module name is
reported, otherwise the real module name is. Since the iOS build reports
the real module name, the mangling code doesn't bother including the
extension-context infix, instead just opting to include the parent
type's name and moving on.

This PR routes around this issue by passing the
`RespectOriginallyDefinedIn` variable to the
`ExtensionDecl::isInSameDefiningModule` method, and using that to skip
the alternate module name entirely. It also sets
`RespectOriginallyDefinedIn` to `false` in more places when mangling
USRs, but i'm not 100% confident that it was all necessary. The goal was
to make USRs more consistent across platforms, regardless of the
surrounding context.
QuietMisdreavus added a commit that referenced this pull request Jul 1, 2025
…#82657)

- **Explanation**: USR mangling can include an extension context infix
(`AAE`) when an extended type uses `@_originallyDefinedIn` on platforms
other than the active one. This adds a check for the
`RespectOriginallyDefinedIn` flag when checking extension decls against
their extended type.
- **Scope**: Changes USR mangling in these situations so that USRs are
the same for the same code regardless of platform.
- **Issues**: rdar://152598492
- **Original PRs**: #82348
- **Risk**: Low. The change is limited to situations where the name
mangler is already disrespecting the alternate module name, and only
additionally turns on that flag for any USR mangling.
- **Testing**: Automated tests
- **Reviewers**: @edymtt @augusto2112
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