Selective control of implicit copying behavior: `take`, `borrow`, and `copy` operators, `@noImplicitCopy`

This looks great to me overall! Very nice to have a more complete picture of the ownership story related to take.

This as the headline motivating example of take remains unsatisfying to me. The text says take is introduced to solve the problems that 1) there is no "strong guarantee" that the compiler will optimize the lifetime of y to end before the final use of x and 2) future modifications of the code may introduce uses of y that inadvertently extend its lifetime. But as far as (1) goes, it seems even with take we have no such "strong guarantee":

And (2) still seems problematic since it does nothing for introducing new uses of x that are interleaved with the 'critical section' where y is alive, e.g.:

func test() {
  var x: [Int] = getArray()
  x.append(5)
  
  var y = x
  longAlgorithmUsing(&y)

  x.append(6) // non-unique!

  consumeFinalY(take y)

  x.append(7)
}

When I raised this previously it was pointed out that the solution I was reaching for seemed similar to the borrow variables discussed in the updated ownership roadmap, but that still leaves me with questions in regards to take. Is some form of borrow variables the intended solution here? If so, why is this example being used to motivate take?

Ought we have some sort of marker in these cases at the point where the non-transitivity of @noImplicitCopy causes us to lose its guarantees? It seems a bit silly to provide the functionality of @noImplicitCopy and also allow it to end up getting silently discarded.

And somewhat relatedly, is copy intended to guarantee that the compiler really will emit a copy operation, or does it just serve to allow the compiler to emit a copy when necessary? If the latter, would it make sense to just use copy as that marker to indicate that you may end up copying the value by passing it somewhere that loses its @noImplicitCopy-ness?