# \`todo!()\` should prevent "unused\_variables" warning

**URL:** <https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542>\
**Category:** compiler\
**Created:** [March 26, 2024, 11:23pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542 "2024-03-26T23:23:50Z")\
**Posts on this page:** 9\
**Page:** 3

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [April 9, 2024, 1:27pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/41 "2024-04-09T13:27:59Z")

</div>

Probably you were thinking about `*mut !`. That type should be inhabited, because could operate on it in generic code:

```rust
use std::mem::MaybeUninit;

fn set_value<T>(f: impl FnOnce() -> T) -> T {
    unsafe {
        let mut x = MaybeUninit::<T>::uninit();
        // When `T == !`, this is `*mut !`.
        let p: *mut T = x.as_mut_ptr();
        p.write(f());
        x.assume_init()
    }
}

fn main() {
    set_value(|| loop {});
}

```

Offtopic: is there an existing discussion on the soundness of `MaybeUninit<ZST>::uninit().assume_init()`, or `transmute::<ZST1, ZST2>()`? This looks sound for "normal" ZSTs, i.e. unit types, non-capturing closures, function types, and compositions of those. But I have just realized that it is assumed that `size_of::<Uninhabited>() == 0`, while the above expressions where one of ZSTs is uninhabited are unsound.

---

<div class="post-metadata">

**Author:** ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)\
**Post date:** [April 9, 2024, 3:08pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/42 "2024-04-09T15:08:35Z")

</div>

Even for normal ZSTs it isn't sound to create one using transmute or assume\_init if the existence of the ZST is used as unforgable token. For example to indicate that some initialization has happened or that interrupts are disabled.

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [April 9, 2024, 4:04pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/43 "2024-04-09T16:04:12Z")

</div>

That's library UB, not language UB. Depending on the way one uses the forged value, it may not be unsound.

My use case is deserializing adapter types (like adapters of iterators or futures) which accept non-capturing closures. There is no way to put a "function or non-capturing closure" bound on the type, and there is [still no way](https://github.com/rust-lang/rfcs/issues/3000) to create functions and non-capturing closures, given their type, even though it's known that the type has a unique value. I have a newtype adapter for such clsoures & functions which implements `Deserialize` and `Default` via `transmute::<(), F>()`, and basically the only thing one can do with the resulting value is call the wrapped value, provided that `F: FnMut`. The `FnMut` bound is satisfied only for real closures and functions, not user-defined tokens (yes, this is also not strictly guaranteed, but it's true and looks unlikely to change in foreseeable future).

`!` type throws a wrench, because it implements `FnMut`, even though it's not really a function (actually, [it doesn't](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=eb17cbd6909e9490ce8e5e1bd2eca3fa), but I don't know whether it's a deliberate decision or an accident; the "`!` implements everything it can" logic would suggest the latter).

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [April 9, 2024, 9:00pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/44 "2024-04-09T21:00:00Z")

</div>

> [@afetisov](#):
>
> (actually, [it doesn't](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=eb17cbd6909e9490ce8e5e1bd2eca3fa))

Side note, what is that error/help message supposed to mean. Reproduced:

```rust
fn f<F: FnMut()>() {}
fn main() {
    f::<u32>();
}
----
error[E0277]: expected a `FnMut()` closure, found `u32`
...
  = note: wrap the `u32` in a closure with no arguments: `|| { /* code */ }`
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^???

```

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [April 9, 2024, 9:48pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/45 "2024-04-09T21:48:18Z")

</div>

A suggestion that's [maybe applicable when the closure is an argument.](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2e58d363a9f666b6cacca58bf1842e22) Should be suppressed when there is no argument and/or when an explicit type that doesn't meet the bound has been specified (e.g. by turbofish).

Seems like a sort of iffy suggestion in general if the type doesn't match the return type of the closure, IMO.

---

<div class="post-metadata">

**Author:** ![fmease](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/fmease/32/12726_2.png) [@fmease](https://internals.rust-lang.org/u/fmease)\
**Post date:** [April 12, 2024, 11:18pm UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/46 "2024-04-12T23:18:14Z")

</div>

I'm late to the party since I only found out about this thread through a related GH issue and since I don't use IRLO.

Regarding `!` impl'ing all traits in existence / making `todo!()` (with inference fallback `!` instead of `()`) work as the return expression of `-> impl Trait` functions, we've had extensive technical discussions about this in [Return-position impl Trait is not satisfied by divergent/never type · Issue #113875 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/113875) which I'm assigned to and which @compiler-errors and I are inclined to close as WONTFIX as soon as we document it as a language / type system guarantee in the Reference (with a lang or types FCP).

I've only skimmed this thread but you've also started to dig into the technical details (traits with associated types, etc.).

I've stalled on opening a PR to the Reference but let me do that right now.

---

<div class="post-metadata">

**Author:** ![gloria\_mundi](https://avatars.discourse-cdn.com/v4/letter/g/7c8e57/32.png) [@gloria\_mundi](https://internals.rust-lang.org/u/gloria_mundi)\
**Post date:** [April 13, 2024, 2:11am UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/47 "2024-04-13T02:11:36Z")

</div>

> [@quaternic](#):
>
> Rather, `example` would ideally be compiled as if you had defined a brand new type and implemented `Iterator<Item = String>` for it.

This would require implementing the trait for this brand new type, which causes problems in exactly the same cases where we cannot implement the trait for `!`, since [it is possible to witness the real type of an existential](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3d15dcdfbc1bb18d222eb18837042c5c).

I don't think it is possible to coerce `!` to `impl Trait` if `Trait` has associated functions. Consider the following:

```rust
trait Trait { fn f() -> !; }
fn g<T: Trait>(_: fn() -> T) -> ! { T::f() }
fn h() -> impl Trait { todo!() }

fn what() -> ! { g(h) }

```

By its type, `what` must diverge, but where? `h` is never called, and no other part of the code panics or loops.

That being said, if `Trait` doesn't have associated types (or all associated types have been explicitly specified) and all functions of `Trait` accept an argument of type `Self`, `&Self` or `&mut Self`, the "brand new type" approach seems sensible.

---

<div class="post-metadata">

**Author:** ![Vorpal](https://avatars.discourse-cdn.com/v4/letter/v/aca169/32.png) [@Vorpal](https://internals.rust-lang.org/u/Vorpal)\
**Post date:** [April 13, 2024, 9:24am UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/48 "2024-04-13T09:24:30Z")

</div>

> [@fmease](#):
>
> Regarding `!` impl'ing all traits in existence / making `todo!()` (with inference fallback `!` instead of `()`) work as the return expression of `-> impl Trait` functions, we've had extensive technical discussions about this in [Return-position impl Trait is not satisfied by divergent/never type · Issue #113875 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/113875) which I'm assigned to and which @compiler-errors and I are inclined to close as WONTFIX as soon as we document it as a language / type system guarantee in the Reference (with a lang or types FCP).

I see that the last comment (over a month ago) in that thread is so one suggesting more helpful diagnostics. Implementing that would help alleviate some of the problems with this.

I don't think the bug you linked shouldn't be closed as won't fix until the diagnostics have been improved.

---

<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:** [July 12, 2024, 9:25am UTC](https://internals.rust-lang.org/t/todo-should-prevent-unused-variables-warning/20542/49 "2024-07-12T09:25:12Z")

</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/todo-should-prevent-unused-variables-warning/20542.md?page=2)
