Skip to content

IRGen: Fix miscompile when a generic parameter is fixed to a tuple containing a pack #81564

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 21, 2025

Conversation

slavapestov
Copy link
Contributor

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.

@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke 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
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test Windows

@slavapestov slavapestov merged commit 490edfa into swiftlang:main May 21, 2025
3 checks passed
hamishknight added a commit to hamishknight/swift that referenced this pull request May 22, 2025
Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis left a comment

Choose a reason for hiding this comment

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

LGTM

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.

Generic type parameter pack combining operation crash
2 participants