This is very much like a macro I wrote for my own library, in which I called it @DeAsync. Mine looks like this:
@attached(peer, names: overloaded)
internal macro DeAsync(replacing oldTypes: [Any.Type] = [],
with newTypes: [Any.Type] = [],
stripSendable: StripSendable = .none)
oldTypes and newTypes are for when you have types, such as callback typealiases, that need to be swapped out. The stripSendable parameter allows for stripping Sendable from the attached function, its parameters, or both.