Skip to content

[6.2] IRGen: Fix miscompile when a generic parameter is fixed to a tuple containing a pack #81565

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
May 20, 2025

Conversation

slavapestov
Copy link
Contributor

@slavapestov slavapestov commented May 16, 2025

6.2 cherry-pick of #68130.

  • Description: Fixes a miscompile if you fix a generic parameter of a nominal type to a tuple containing a pack expansion:

    struct G<T> {
      func f<each U>(_: repeat each U) where T == (repeat each U) {}
    }
    

    If you then call f() with a one-element pack, we would crash at runtime.

  • Origination: Regression was introduced with this change in Swift 5.10: IRGen: Fulfill pack metadata from tuple metadata #68130

  • Risk: Low. This does change the calling convention, but not the mangling, in this specific scenario where the old calling convention passed the wrong information. This change reverts to the Swift 5.9 calling convention, since the specific pattern was only intended to kick in with tuple conformance witness thunks.

  • Reviewed by: TBD

@slavapestov slavapestov requested a review from a team as a code owner May 16, 2025 18:27
@slavapestov
Copy link
Contributor Author

@swift-ci Please test

…ntaining a pack

If you had something like:

    struct G<T> {
      func f<each U>(_: repeat each U) where T == (repeat each U) {}
    }

We would fulfill 'each U' from the metadata for 'G<(repeat each U)>',
by taking apart the tuple metadata for `(repeat each U)` and forming
a pack.

However this code path was only intended to kick in for a tuple
conformance witness thunk. In the general case, this optimization
is not correct, because if 'each U' is substituted with a
one-element pack, the generic argument of `G<(repeat each U)>` is
just that one element's metadata, and not a tuple. In fact, we
cannot distinguish the one-element tuple case, because the wrapped
element may itself be a tuple.

The fix is to just split off FulfillmentMap::searchTupleTypeMetadata()
from searchTypeMetadata(), and only call the former when we're in
the specific situation that requires it.

- Fixes swiftlang#78191.
- Fixes rdar://problem/135325886.
@slavapestov slavapestov force-pushed the fix-issue-78191-6.2 branch from 8194e78 to 85bdf45 Compare May 16, 2025 21:35
@slavapestov
Copy link
Contributor Author

@swift-ci Please test

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

LGTM

@slavapestov slavapestov merged commit 7a334bc into swiftlang:release/6.2 May 20, 2025
5 checks passed
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