Sure, you could only use channels and you'd never get races,
but in practice that'd be unwieldy and slow, which is why people write traditional lock-based sync stuff in Go all the time, and depend on old-fashioned debugging (and the race-checker).
Rust really fixes this (with its ownership system), but it wasn't easy.