IIRC/IIUC, Go in 2011 only supported a single logical processor (P) in its runtime model of (G)oroutines, Logical (P)rocessors, and (M)achine threads. It's possible channels didn't require any atomic operations at all. I'd be surprised if a coroutine style implementation would have been faster, as resuming and yielding coroutines typically involve more operations then entering into and returning from a function[1], but the overhead might have been low-enough to be negligible relative to elegance of the lexer code. (Inverting consumer/producer calling patterns is one of the areas at which coroutines excel, especially stackful coroutines where you can make full use of the stack as an implicit data structure.)
[1] Coroutines in Lua are relatively cheap, but because they have to do exception handling bookkeeping (i.e. setjmp) they're still more expensive than a regular function call. This is specific to Lua and not a necessary part of implementing coroutines. However, I can't imagine a situation where coroutines would be faster than a regular function call, and difficult to imagine them having the same cost unless a language uses a completely discontiguous stack for all call frames. In general coroutines have the same cost as a function call plus the need to save/restore at least some additional stack information.