# Compile-time checked version of \`unimplemented!()\`

**URL:** <https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837>\
**Category:** language design\
**Created:** [February 22, 2017, 7:25pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837 "2017-02-22T19:25:28Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 22, 2017, 7:25pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/1 "2017-02-22T19:25:28Z")

</div>

I posted this idea as an RFC issue [in #1911](https://github.com/rust-lang/rfcs/issues/1911), but figured I’d post here as well to get some feedback.

The linked issue has some further technical details, but the basic idea is to introduce a construct to indicate that a piece of code _needs_ to be filled in (i.e., the program should not compile while it is present), but that the developer wants to postpone coding up until later. This came about following a rather large refactor I had to do; part of the work I had to do was replace all `Foo`s and `Bar`s with `Baz`s. But while doing so, there were times when I realized some other change would need to be made (like `Baz` requiring some additional information, but that information not being readily available in a particular segment of the code). I wanted to first finish translating all the `Foo`s and `Bar`s, and only _after_ that deal with the corner cases.

Normally in this case, I add a `// TODO`, or an `unimplemented!()`. However, this approach has some drawbacks. In particular, these both still let the code compile when present. Thus, after I finished my “first pass” I had to _remember_ to also grep for all the `unimplemented()`s and `// TODO`s (_and_ filter out any that aren’t relevant to the refactor in question). What I _really_ wanted was a way to tell the compiler “don’t let the code compile while this is unimplemented”. But crucially, I still want to check if my code type-checks and if the borrow checker is satisfied. The compiler should only remind me of those locations if the code _would otherwise have compiled_.

I realize that this feature is kind of weird — it’s a construct that will never be present in any distributed code (because, by definition, it prevents compilation). But I believe it would be extremely useful during development, especially of large passes like refactors, building a new, big feature, or writing a bunch of code from scratch.

Thoughts?

---

<div class="post-metadata">

**Author:** ![skade](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skade/32/3333_2.png) [@skade](https://internals.rust-lang.org/u/skade)\
**Post date:** [February 22, 2017, 8:04pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/2 "2017-02-22T20:04:55Z")

</div>

Isn’t that just a very weak version of “typed holes” that - for example - Idris has?

Also, why would you not want to run it? This allows you to test finished branches while others are still I’m construction.

---

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 22, 2017, 8:24pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/3 "2017-02-22T20:24:11Z")

</div>

It’s similar, but not _quite_ the same if I understand Typed Holes correctly. A typed hole is an instruction to the compiler that you don’t know what _type_ you want in a particular location, and that you’d like it to tell you what can. Whereas this is telling the compiler _I haven’t completed this code yet_, and that you simply want it to warn you if you try to compile the code with that segment still unfilled.

If the hole is something that you expect not to be encountered, or to only be encountered infrequently, using `unimplemented!()` and having it panic at runtime would be fine. The kind of uses I envision for this is when there are key pieces of logic missing, that you _know_ the program can’t do without. And running without those implemented is pretty much guaranteed to not work, so your program should simply not compile.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 22, 2017, 9:55pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/4 "2017-02-22T21:55:26Z")

</div>

```rust
struct Unimplemented;

```

Then create an `Unimplemented` everywhere you want it not to compile? This should surely be a type error.

---

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 22, 2017, 11:12pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/5 "2017-02-22T23:12:54Z")

</div>

Ah, but that would prevent, say, the borrow checking stage from running. And it will cause all sorts of downstream errors in that code because the variable in question will be of the wrong type.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 22, 2017, 11:26pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/6 "2017-02-22T23:26:56Z")

</div>

One could write a clippy lint for `unimplemented!` and deny it?

---

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 22, 2017, 11:34pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/7 "2017-02-22T23:34:14Z")

</div>

Except that I actually want `unimplemented!()` in my code too. I use that whenever there’s some weird corner case that I don’t know how to deal with yet, that I think will never be run into in practice, or that is just particularly finicky. `incomplete!()` would be used during development for things I _know_ **must** be completed for anything to work.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [February 22, 2017, 11:58pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/8 "2017-02-22T23:58:05Z")

</div>

Then write a lint for `incomplete!`? Or use `panic!("unimplemented")` for the ones you don’t want to trigger a lint?

You can’t have a type error and then do borrowck on it, after all. A lint that gets translated into a hard error afterwards is done is the only way to do this.

---

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 23, 2017, 12:26am UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/9 "2017-02-23T00:26:15Z")

</div>

Well, ideally I’d want it to not be a type error (see for example @cuviper’s suggestion [here](https://github.com/rust-lang/rfcs/issues/1911#issuecomment-281786580)). You are of course right that this could be implemented using a clippy lint, but I feel like this is in a very similar spirit to `unreachable!()` and `unimplemented!()`, and would benefit from being a built-in. Furthermore, making it a clippy lint would mean a) that your code needs to be clippy clean for it to be visible, and crucially b) that you must run clippy every time you compile…

---

<div class="post-metadata">

**Author:** ![sinkuu](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sinkuu/32/5819_2.png) [@sinkuu](https://internals.rust-lang.org/u/sinkuu)\
**Post date:** [February 23, 2017, 2:13am UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/10 "2017-02-23T02:13:55Z")

</div>

> [@jonhoo](#):
>
> making it a clippy lint would mean a) that your code needs to be clippy clean for it to be visible, and crucially b) that you must run clippy every time you compile...

It's easy to skip clippy lints except ones you want:

```rust
#![allow(clippy)]
#![deny(unimplemented)]

```

Or `cargo clippy -- -A clippy -D unimplemented`. And if you don't want to manually invoke `cargo clippy`, you could do `#![plugin(clippy)]` so that clippy is run everytime you compile. I'd like a built-in, allow-by-default lint for `unimplemented!()` though.

---

<div class="post-metadata">

**Author:** ![jugglerchris](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jugglerchris/32/2661_2.png) [@jugglerchris](https://internals.rust-lang.org/u/jugglerchris)\
**Post date:** [February 24, 2017, 5:24pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/11 "2017-02-24T17:24:47Z")

</div>

It sounds like a call to a non-existant external function, which would fail at link time, would be close to what you want.

---

<div class="post-metadata">

**Author:** ![jonhoo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jonhoo/32/3367_2.png) [@jonhoo](https://internals.rust-lang.org/u/jonhoo)\
**Post date:** [February 24, 2017, 5:54pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/12 "2017-02-24T17:54:28Z")

</div>

Yeah, @cuviper brought that up in [the RFC issue](https://github.com/rust-lang/rfcs/issues/1911#issuecomment-281786580), but the drawback is that at the linking stage we’ve lost the location information for the `incomplete!()` that triggered it.

I’ve made [a crate](https://github.com/jonhoo/incomplete) that abuses an existing compiler lint to get something close to what I want, but it’s not quite as good as a compiler-supported version would be

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [February 24, 2017, 6:26pm UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/13 "2017-02-24T18:26:26Z")

</div>

The link error does point to the referring function, at least when linking with gcc: [playground](https://is.gd/zWPefE)

```rust
extern { fn foo(); }
fn main() { unsafe { foo() } }

```

```nohighlight
error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" [...]
  = note: ./out.0.o: In function `rust_out::main':
/tmp/<anon>:2: undefined reference to `foo'
collect2: error: ld returned 1 exit status

```

One advantage here is that `incomplete!()` will still compile if that code is never actually used at all.

---

<div class="post-metadata">

**Author:** ![bjadamson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjadamson/32/52_2.png) [@bjadamson](https://internals.rust-lang.org/u/bjadamson)\
**Post date:** [February 25, 2017, 2:35am UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/14 "2017-02-25T02:35:03Z")

</div>

Why not just use a syntax error with a custom error message behind a macro?

---

<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:28am UTC](https://internals.rust-lang.org/t/compile-time-checked-version-of-unimplemented/4837/15 "2019-03-25T08:28:00Z")

</div>

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