Limitations of `borrowing` / why not first-class borrowed references?

struct Noncopyable: ~Copyable {}

func doSomething(_ n: borrowing Noncopyable? = nil) {}

let n = Noncopyable()
doSomething(n) // error: implicit conversion to 'Noncopyable?' is consuming

Yeah, makes sense. I understand why it happens, and how I can work around it:

func doSomething() {}
func doSomething(_ n: borrowing Noncopyable) {}

It's just annoying, that this Swift pattern that's used everywhere, is another that's not applicable to non-copyable types. It's particularly annoying as a Rust programmer, because something similar is possible in Rust:

fn do_something(n: Option<&Noncopyable>) {}

In swift, roughly, Optional<borrowing Noncopyable>, which isn't allowed.

And it kinda feels like the resolution not to introduce first-class references is adding a lot to the complexity of the language. We have noncopyable types now, we have nonescaping types now, why can't we have first-class references? I feel like it would overall simplify the language, since you could get use get accessors of &Noncopyable rather than needing _read, you could support optional borrows like my example here, you wouldn't need the borrowing keyword at all, etc.

2 Likes