I think it might be stretching it a bit to say that one lesser used exception makes the whole system copy/reference system confusing. There is also the upside that if you know what you are doing you can extract significant improvements in performance by being able to specify which passing method is used; a fair number of newer languages offer you no such option.
I do appreciate the additional optimization opportunities that derive from the fact that user defined types can be used as values and not just references like in Java. That's very important for memory usage.
But the complexity that comes with it is undeniable. It's not just one exception that is confusing. The whole business with nil interface values versus non-nil interface values that contain nil pointers is not exactly pretty. It is consistent though.
I don't dispute the usefulness of being able to control how parameters are passed, especially in a systems language. But it seems like the two ways of passing could be consistently marked by syntax. They are in C, C++, and Rust, right? In Rust, if you had some type 'channel', then:
fn spam(victim: channel)
takes the channel by value (impossible in Go, and probably nonsensical anyway), whereas:
fn spam(victim: @channel)
takes a pointer to the channel.
I think the str type is currently an exception to this in Rust.