I also found out that keeping the same signature as Apple's (but enforcing the AnyObject constraint) automatically fixes the memory leak everywhere:
extension Publisher where Failure == Never {
func assign<Root: AnyObject>(to keyPath: ReferenceWritableKeyPath<Root, Output>, on root: Root) -> AnyCancellable {
sink { [weak root] in
root?[keyPath: keyPath] = $0
}
}
}