SE-0366 (second review): `take` operator to end the lifetime of a variable binding

It also seems strange because I can pass a borrow function parameter to another function which accepts its parameter by take (because the compiler will insert an implicit copy), but I can't actually perform a take manually.

func someFunction<T>(_ x: /* implicit: borrow */ T) {

  takesArg(x) // ok, compiler inserts a copy

  let _ = take x // error: 'x' is not 'take'
}

func takesArg<T>(_ x: take T) {

  let _ = take x // ok...
}

I wonder if that's going to feel confusing to people.

1 Like

Would it be better to make this a warning rather than an error? It has no semantic effect at run time, and (if the compiler takes it literally as ā€œproduce an owned valueā€) a negative performance effect, but it doesnā€™t otherwise make the program invalid. That would be in line with similar warnings like ā€œcast always succeedsā€.

(The take operator does have a compile-time effect, that of ending the lifetime of the original name, but I agree itā€™s better not to allow that if it doesnā€™t come with the run-time effect of releasing the value.)

8 Likes

I'll provide a complete summary of the review outcome with the acceptance, but since this is right at the top: the Language Workgroup discussed this and we decided that we'd like more real-world experience with take/consume before considering downgrading this restriction. It's easy to remove restrictions later. It's not easy to add back a restriction later if we find that only producing a warning is harmful or confusing in practice.

1 Like

Thanks everyone for your feedback so far! I've kicked off another re-review of SE-0366 here:

Please provide further feedback on the new review thread. Thank you!

Holly Borla
Review Manager