about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-03-19 15:16:43 +0100
committerGitHub <noreply@github.com>2019-03-19 15:16:43 +0100
commitd4dd8604eb76683e1bb613cc35d3ad970f4d372f (patch)
tree95a2b55faa646337fd6ad3bb901c0112aa5f3fed /src/libcore
parentef4d1c419525e1510aa650e2bec0d8f7449a2130 (diff)
parent9d408d972f7cf16162ec3ab35e11c659ccee9566 (diff)
downloadrust-d4dd8604eb76683e1bb613cc35d3ad970f4d372f.tar.gz
rust-d4dd8604eb76683e1bb613cc35d3ad970f4d372f.zip
Rollup merge of #56348 - matklad:todo-macro, r=withoutboats
Add todo!() macro

The primary use-case of `todo!()` macro is to be a much easier to type
alternative to `unimplemented!()` macro.

EDIT: hide unpopular proposal about re-purposing unimplemented

<details>
However, instead of just replacing `unimplemented!()`, it gives it a
more nuanced meaning: a thing which is intentionally left
unimplemented and which should not be called at runtime. Usually,
you'd like to prevent such cases statically, but sometimes you, for
example, have to implement a trait only some methods of which are
applicable. There are examples in the wild of code doing this thing,
and in this case, the current message of `unimplemented`, "not *yet*
implemented" is slightly misleading.

With the addition of TODO, you have three nuanced choices for a
`!`-returning macro (in addition to a good-old panic we all love):

  * todo!()
  * unreachable!()
  * unimplemented!()

Here's a rough guideline what each one means:

- `todo`: use it during development, as a "hole" or placeholder. It
  might be a good idea to add a pre-commit hook which checks that
  `todo` is not accidentally committed.

- `unreachable!()`: use it when your code can statically guarantee
  that some situation can not happen. If you use a library and hit
  `unreachable!()` in the library's code, it's definitely a bug in the
  library. It's OK to have `unreachable!()` in the code base,
  although, if possible, it's better to replace it with
  compiler-verified exhaustive checks.

- `unimplemented!()`: use it when the type checker forces you to
  handle some situation, but there's a contract that a callee must not
  actually call the code. If you use a library and hit
  `unimplemented!()`, it's probably a bug in your code, though
  it *could* be a bug in the library (or library docs) as well. It is
  ok-ish to see an `unimplemented!()` in real code, but it usually
  signifies a clunky, eyebrow-rising API.
</details>
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/macros.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index b052f59b0f5..d77936c7ddd 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -559,6 +559,65 @@ macro_rules! unimplemented {
     ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
 }
 
+/// A standardized placeholder for marking unfinished code.
+///
+/// This can be useful if you are prototyping and are just looking to have your
+/// code typecheck. `todo!` works exactly like `unimplemented!`, there only
+/// difference between the two macros is the name.
+///
+/// # Panics
+///
+/// This will always [panic!](macro.panic.html)
+///
+/// # Examples
+///
+/// Here's an example of some in-progress code. We have a trait `Foo`:
+///
+/// ```
+/// trait Foo {
+///     fn bar(&self);
+///     fn baz(&self);
+/// }
+/// ```
+///
+/// We want to implement `Foo` on one of our types, but we also want to work on
+/// just `bar()` first. In order for our code to compile, we need to implement
+/// `baz()`, so we can use `todo!`:
+///
+/// ```
+/// #![feature(todo_macro)]
+///
+/// # trait Foo {
+/// #     fn bar(&self);
+/// #     fn baz(&self);
+/// # }
+/// struct MyStruct;
+///
+/// impl Foo for MyStruct {
+///     fn bar(&self) {
+///         // implementation goes here
+///     }
+///
+///     fn baz(&self) {
+///         // let's not worry about implementing baz() for now
+///         todo!();
+///     }
+/// }
+///
+/// fn main() {
+///     let s = MyStruct;
+///     s.bar();
+///
+///     // we aren't even using baz() yet, so this is fine.
+/// }
+/// ```
+#[macro_export]
+#[unstable(feature = "todo_macro", issue = "59277")]
+macro_rules! todo {
+    () => (panic!("not yet implemented"));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+}
+
 /// A macro to create an array of [`MaybeUninit`]
 ///
 /// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.