# "out" function arguments?

**URL:** <https://internals.rust-lang.org/t/out-function-arguments/8563>\
**Category:** Uncategorized\
**Created:** [October 15, 2018, 11:59am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563 "2018-10-15T11:59:34Z")\
**Posts on this page:** 5\
**Page:** 2

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 16, 2018, 4:24am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563/21 "2018-10-16T04:24:16Z")

</div>

> [@leonardo](#):
>
> So “out” arguments are missing.

I think the problem for Rust here is that in those languages, `out` is generally a _parameter mode_ not a _type_. So when you have, say, `bool TryGet(out string foo)` in C#, you can't put an `out string` into a datatype, and thus the compiler can check that you actually initialize it before the function returns. (With a massive asterisk on that statement, because `out` doesn't actually exist in the .Net VM, and thus it's actually just a compiler lint and the bytecode is still default-initializing it before passing it as a `mut`.)

What would it mean to put an `&out` into a data structure? What happens if you then (safely!) leak that data structure?

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [October 16, 2018, 4:40am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563/22 "2018-10-16T04:40:41Z")

</div>

In the formulation in my RFC, `&out` means write-only. As an effect of this, it also does not drop old values, (because that would require at least 1 read). So putting `&out` in a data structure could mean that the data structure is a proxy that allows you to write into something else.

For example, graphics buffers managed by the OS. It would not be safe to deallocate that buffer, so you would only have a `&out` reference to the buffer, and therefore you could write to it, but not read from it.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 16, 2018, 5:19am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563/23 "2018-10-16T05:19:56Z")

</div>

> [@RustyYato](#):
>
> In the formulation in my RFC [...]

`out` arguments, as I'm used to them, are what I think your RFC termed `&uninit`, requiring that

> Functions and closures that take a `&uninit T` argument must initialize it before returning

Which leads to a whole bunch of questions, like "what happens if I make a `Vec<&uninit T>`?

Rust turning its parameter modes into real types in the pre-1.0 days was a big part of its value, I think, so I'd hate to lose that with a bunch of limitations like "You cannot return an `&uninit T`". (What would that mean for generics, anyway?)

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [October 16, 2018, 5:29am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563/24 "2018-10-16T05:29:30Z")

</div>

> [@scottmcm](#):
>
> Which leads to a whole bunch of questions, like "what happens if I make a `Vec<&uninit T>` ?

This is expressly forbidden. `&uninit` is kinda like `out` in C#, just a compiler hint.

> [@scottmcm](#):
>
> Rust turning its parameter modes into real types in the pre-1.0 days was a big part of its value, I think, so I’d hate to lose that with a bunch of limitations like "You cannot return an `&uninit T` ". (What would that mean for generics, anyway?)

I'm not sure how to turn `&uninit` into a type. Because of this, I decided that, for now, it is fine if `&uninit` wasn't a type. If there is a way to change that, then a future RFC could change that if my RFC goes through.

> [@scottmcm](#):
>
> "You cannot return an `&uninit T` ". (What would that mean for generics, anyway?)

In an older version of my RFC, I did have that you can't return a &uninit T, but that has since been removed.

> [@scottmcm](#):
>
> Functions and closures that take a `&uninit T` argument must initialize it before returning

What I mean by this is that if a function returns normally (without panicking), then all uninitialized values must be initialized. This is useful because it gives some guarantees when calling functions, if you call a function and it takes an `&uninit`, you know after the function that the value must have been initialized. It allows for purely local analysis of code.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:16am UTC](https://internals.rust-lang.org/t/out-function-arguments/8563/25 "2019-03-25T08:16:53Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/out-function-arguments/8563.md?page=1)
