Is this a bug in automatic reference counting?

Many expressions have to produce an independent value that the evaluating context will has independent ownership of: functions have to return independent values, getters have to return independent values, and so on. Other expressions don’t: most importantly, references to stored variables or properties. (This is all getting more complicated as we introduce more support for lifetime-dependent values, but for now, this is the big picture.)

The big concern about implicitly forwarding values is that forwarding necessarily means the caller loses access to the value. If the caller actually needs the value to stay alive, either because it’s going to use it again or because the program as a whole has an implicit dependency on its lifetime (e.g. because of a weak reference somewhere else), the forward can break behavior.

But that’s really only a problem with expressions that don’t naturally produce an independent value. If you use a call expression directly as an argument for a consuming parameter, the current context doesn’t have any other way of referring to that result, so it obviously can’t directly use it again later. Along similar lines, forwarding it could end up shortening its lifetime and invalidating weak references earlier, but it doesn’t really seem reasonable that someone would expect the the current context to keep this temporary value alive arbitrarily. So there’s no good reason not to implicitly forward into the parameter.

Yes. The callee simply receives a value that it has ownership of, with no idea how that was produced.

3 Likes

Thank you for tirelessly explaining this to us, but I'm a little bit confused by your last statement in this post. You replied to my question with "Yes.", but I suppose you actually mean "No", right?

My understanding of your other lines is this: in a scenario of a function func foo(_ a: consuming A) being invoked as foo(someExpressionOfA), the compiler will insert implicit copies from the "caller" (not the "callee") side when it cannot tell someExpressionOfA can produce an independent value. Am I right?

2 Likes

Ah, yes, sorry. The problem with caller/callee terminology is that I misread it about 20% of the time. It is the caller’s responsibility.

Correct. The semantics are that we emit the expression in a way that produces an independent value, which may require copies.

3 Likes