# Those-Which-Must-Not-Be-Named (i.e., everything we can't name)

**URL:** https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844
**Category:** Uncategorized
**Created:** [July 1, 2018, 9:14pm UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844 "2018-07-01T21:14:16Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 1, 2018, 9:14pm UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/1 "2018-07-01T21:14:16Z")

</div>

I’ve seen a few threads lately trying to come up with syntaxes for unnameable entities. I figured I’d make a complete list of everything that is currently unnameable, so that we can try to deal with it all at once. This is all in absence of `typeof`, of course.

This is an incomplete list based off my excellent^W iffy memory. Let me know if I missed anything!

# Types

- The type of a function.

```rust
fn foo(_: T) -> U { .. }
// problem: I can't name the ZST that the following types as:
let bar = foo;
// workaround:
type foo_t = impl Fn(T) -> U;
let bar: foo_t = foo;

```

- The type of a fn-local item (struct, enum, type, etc)

```rust
// problem: I can't name `???` outside the fn scope
fn foo() -> ??? {
    struct Foo;
    Foo
}
// workaround:
struct Foo;
fn foo() -> Foo {
    Foo
}

```

- The type of a closure.

```rust
fn foo() -> impl Fn() -> i32 {
    || 0
}
// same problem as the type of a function, really

```

- Output of a function.

```rust
fn foo() -> i32 { 0 };
// problem: how can I name this type without naming it again?
let bar = foo();
// workaround via assoc. type
type foo_t = impl Fn<()>;
let _: foo_t = foo;
let bar: foo_t::Output = foo();

```

# Values

- Fn-local item (fn, const, static).

```rust
fn foo() {
    fn bar() {}
}
// problem: how do I name bar outside of foo?
let baz = foo::bar;

```

- The captures of a closure. One can argue that those can’t be made `pub` though.

```rust
let a = 0;
let b = 1;
let bar = move |x| x + a - b;

let mut baz = bar.clone();
// problem: how do I do this? (assuming the field's 
// name is the same as the capture's)
baz.b = 1;
// workaround: transmute! (or ptr casts) this is unstable though
// and maybe even UB!
unsafe { *transmute::<_, *mut i32>(&mut baz).offset(1) = 1; }

```

# Lifetimes

- The lifetime of a function’s body.

```rust
fn foo(x: T) {
    // problem: what lifetime goes here? sure, we can let the compiler
    // infer it but relying on inference to name a lifetime
    // can lead to problems if inference isn't allowed in some palce
    let foo: &'? T = &x;
}

```

- The lifetime of a struct.

```rust
struct MyBox<T: ?Sized> {
    // problem: what lifetime goes here? I need to use `*mut T` instead, 
    // since I can't just say "this pointer lives for as long as this
    // this struct does" (we don't have &move yet but my point stands)
    ptr_to_heap: &'? move T,
}

```

# Solutions

The following are some ideas I’ve had/seen for solving each of these.

- Type of fn: `fn foo` or `foo::type`.
- Type of fn-local item: `(fn foo)::Foo`, `foo::type::Foo`, `foo::Foo`.
- Type of closure:

```rust
// introduce a new type inside the closure by ascribing the closure.
// there's a lot of unresolved problems with this, so it should probably
// be discussed in its own thread
fn foo() -> fn::Closure {
    (|| 0): Closure
    // or
    let closure: Closure = || 0;
    closure
    // or maybe denote that it's a new type with special syntax?
    let closure = struct Closure || 0;
}

```

- Fn output: `foo::return`? `(fn foo)::return`? Could also imagine `foo::yield` for generators.
- Inner fn: same as inner type.
- Closure captures: probably should be described in its own thread.
- Fn body lifetime: `'fn`.
- Struct lifetime: `'self`.

PS: There’s one slightly insane corner case, where it’s impossible to name a lang item (like one of the panic fns) if you don’t know what it’s _actually_ called. Imagine the following:

```rust
#![no_std]

fn my_panic() -> ! {
    __lang__ ::panic_fmt()
}

```

I don’t think this is actually useful in any way, but I figured I’d mention it.

---

<div class="post-metadata">

### Author: ![daboross](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/daboross/32/12645_2.png) [@daboross](https://internals.rust-lang.org/u/daboross)
#### Post date: [July 2, 2018, 1:49am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/2 "2018-07-02T01:49:03Z")

</div>

Functions do have [a type](https://doc.rust-lang.org/std/primitive.fn.html) we can name:

```rust
fn foo(_: T) -> U { .. }
let bar: fn(T) -> U = foo;

```

Agree with everything else here though!

---

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 2, 2018, 1:52am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/3 "2018-07-02T01:52:10Z")

</div>

Not quite. `fn(..) -> T` is a function _pointer_, which has size `mem::size_of<usize>()`. Each function has an associated ZST, which is best illustrated by this [playground link](https://play.rust-lang.org/?gist=888f6774d6a1b6c3436bbd1b3eebc312&version=stable&mode=debug&edition=2015). The following code might also convince you:

```rust
fn foo() {}

let f = foo;
let g: fn() = foo;

println!("{} {}", mem::size_of_val(&f), mem::size_of_val(&g));

```

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [July 2, 2018, 7:08am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/4 "2018-07-02T07:08:25Z")

</div>

> [@mcy](#):
>
> - Fn-local item (fn, const, static).
> 
> ```rust
> fn foo() {
> fn bar() {}
> }
> // problem: how do I name bar outside of foo?
> let baz = foo::bar;
> 
> ```

In my opinion this is not a problem. The user has clearly intentionally hidden `bar` inside `foo`. For all intents an purposes, `foo` then works as a module. I don't think this should change. Furthermore, it might not actually work if you introduce scoped type variables.

> [@mcy](#):
>
> ```rust
> // workaround: transmute! (or ptr casts) this is unstable though
> // and maybe even UB!
> unsafe { *transmute::<_, *mut i32>(&mut baz).offset(1) = 1; }
> 
> ```

Absolutely UB. You are not guaranteed that `b` is at offset `1` and so the behavior is undefined.

---

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 2, 2018, 7:25am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/5 "2018-07-02T07:25:33Z")

</div>

> [@Centril](#):
>
> In my opinion this is not a problem. The user has clearly intentionally hidden `bar` inside `foo` . For all intents an purposes, `foo` then works as a module. I don’t think this should change. Furthermore, it might not actually work if you introduce scoped type variables.

I didn't include this because I wanted my examples to all be syntactically correct, but imagine if I wrote

```rust
fn foo() {
    pub fn bar() {}
}

```

Can't deny that I want the world to see `foo::bar` now! This came up in another thread about fn-local items.

> [@Centril](#):
>
> Absolutely UB.

Yep, I always forget that transmutation of non-`#[repr(C)]` types is UB!

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [July 2, 2018, 8:08am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/6 "2018-07-02T08:08:50Z")

</div>

> [@mcy](#):
>
> I didn’t include this because I wanted my examples to all be syntactically correct, but imagine if I wrote
> 
> ```rust
> fn foo() {
> pub fn bar() {}
> }
> 
> ```
> 
> Can’t deny that I want the world to see `foo::bar` now! This came up in another thread about fn-local items.

Heh. Link to the thread?

```rust
fn foo<T>() {
    pub fn bar(x: T) -> T { x } // Using ~ScopedTypeVariables from Haskell
}

```

And now we have parameterized modules, `foo<u8>::bar(1)`😛

---

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 2, 2018, 8:17am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/7 "2018-07-02T08:17:39Z")

</div>

> [@Centril](#):
>
> Heh. Link to the thread?

> [@Idea: associated items for functions](https://internals.rust-lang.org/t/idea-associated-items-for-functions/7822):
>
> This is something I’ve wanted a lot. It would help when a function returns some type unique to that function, eg. when a function has it’s own error type: fn eat\_snacks() -\> Result\<(), self::eat\_snacks::Error\> { pub enum Error { .. }; ... } It could also help when a function uses constants that you may want to be visible outside the function: fn request\_info\_from\_peers() { pub const NUM\_REQUESTS\_IN\_PARALLEL: usize = 23; ... } #[test] fn test\_request\_info\_from\_peers() { fo…

---

<div class="post-metadata">

### Author: ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)
#### Post date: [July 4, 2018, 8:37am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/8 "2018-07-04T08:37:02Z")

</div>

Another thing came up when writing the [Formalise Reborrows RFC](https://github.com/rust-lang/rfcs/pull/2364) (postponed):

```rust
trait Reborrow {
    // Returns Self but with fresh lifetime parameter(s)
    fn reborrow(&self) -> ???;
}

impl<'a, T: 'a + ?Sized> Reborrow for MyRef<'a, T> {
    fn reborrow<'b>(&self) -> MyRef<'b, T> where 'a: 'b {
        MyRef(self.0)
    }
}

```

---

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 4, 2018, 8:56am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/9 "2018-07-04T08:56:45Z")

</div>

So my knee-jerk reaction is "oh what you totally want is

```rust
// making up syntax to say "Self must have kind `lifetime -> type`"
trait Reborrow where Self<'a> {
    fn reborrow<'b>(&self) -> Self<'b> where 'a: 'b;
}

// and type closures, too
impl<T: ?Sized> Reborrow for |'a| MyRef<'a, T> where T: 'a {
    fn reborrow<'b>(&self) -> Self<'b> where 'a: 'b {
        MyRef(self.0)
    }
}

```

Though… maybe what you want is say the opposite of `T: 'a`? Like… `'a: T`, `'a` outlives all lifetimes in `T`?

```rust
trait Reborrow {
    fn reborrow<'a>(&'a self) -> Self where 'a: Self
}

```

Or maybe something like a “lifetime intersection” `T & 'a`, replace all lifetimes `'t` in `T` with some `'fresh where 'a: 'fresh, 't: fresh` (i.e. the intersection lifetime)?

Let me know which of these matches your thinking.

---

<div class="post-metadata">

### Author: ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)
#### Post date: [July 4, 2018, 9:52pm UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/10 "2018-07-04T21:52:39Z")

</div>

Is a knee-jerk reaction useful? First, you can’t write `Self<'a>` today. Second, there might be more than one lifetime involved. I only mentioned the problem here because you seem to be collecting them.

---

<div class="post-metadata">

### Author: ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)
#### Post date: [July 4, 2018, 9:56pm UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/11 "2018-07-04T21:56:16Z")

</div>

Oops, apparently part of what I wrote down got cut off! What I meant to say is that I think your problem could be solved by higher kinded types, if we got them. It sounds to me like you want a way to express a type operation that forces all contained lifetimes to be shortened (see my `T & 'a` note), rather than to name a type or value that the compiler already reasons about but that isn’t pronounceable in source code.

---

<div class="post-metadata">

### Author: ![dhardy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhardy/32/2399_2.png) [@dhardy](https://internals.rust-lang.org/u/dhardy)
#### Post date: [July 5, 2018, 7:08am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/12 "2018-07-05T07:08:14Z")

</div>

Basically, yes. I was able to test the _implementation_ above, but obviously not the trait. The most tricky thing is supporting multiple lifetime arguments and placing bounds on each. I haven’t been following HKT development so I’ve no idea if there’s anything on the horizon capable of this?

---

<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:30am UTC](https://internals.rust-lang.org/t/those-which-must-not-be-named-i-e-everything-we-cant-name/7844/13 "2019-03-25T08:30:27Z")

</div>

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