Generic parameter shadowing warning and protocol conformance

Swift 5.9 has a new warning:

Generic parameter 'Name' shadows generic parameter from outer scope with the same name; this is an error in Swift 6

At first glance this seems reasonable and is easy enough to fix. However, it seems to fundamentally break the ability of generic types to conform to protocols which declare requirement with generic parameters that share the same name. Take this example from the Swift Composable Architecture:

protocol AnyScopedReducer {
  func rescope<ScopedState, ScopedAction, RescopedState, RescopedAction>(
    _ store: Store<ScopedState, ScopedAction>,
    state toRescopedState: @escaping (ScopedState) -> RescopedState,
    action fromRescopedAction: @escaping (RescopedState, RescopedAction) -> ScopedAction?,
    removeDuplicates isDuplicate: ((RescopedState, RescopedState) -> Bool)?
  ) -> Store<RescopedState, RescopedAction>
}

extension ScopedReducer: AnyScopedReducer {
  @inlinable
  func rescope<ScopedState, ScopedAction, RescopedState, RescopedAction>(
    _ store: Store<ScopedState, ScopedAction>,
    state toRescopedState: @escaping (ScopedState) -> RescopedState,
    action fromRescopedAction: @escaping (RescopedState, RescopedAction) -> ScopedAction?,
    removeDuplicates isDuplicate: ((RescopedState, RescopedState) -> Bool)?
  ) -> Store<RescopedState, RescopedAction> {
    let fromScopedAction = self.fromScopedAction as! (ScopedState, ScopedAction) -> RootAction?
    ...
  }
}

When you control the source this is an easy enough fix, just rename one of the generic parameters. However, this can be undesirable for clarity on either side, so is there a way to resolve the issue while keeping the original naming? Is this warning perhaps somewhat overly broad in the protocol requirement case?

6 Likes