-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add todo!() macro #56348
Add todo!() macro #56348
Conversation
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
internals discussion: https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925 |
Example where Lines 89 to 95 in 3dde9e1
|
I like that this distinguishes intent -- |
This comment has been minimized.
This comment has been minimized.
Oups, was meant to add that to commit message. That obviously should be done, but only when/if we stabilize the |
@@ -553,6 +553,64 @@ macro_rules! unimplemented { | |||
($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); | |||
} | |||
|
|||
/// A standardized placeholder for marking unfinished code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unimplemented macro also has this sentence in the docs so you probably want to re-frame that documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that only when we stabilize todo
: #56348 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't macros insta-stable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are other unstable macros already, like concat_idents!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@steveklabnik I believe not necessarily. The dbg!()
macro went through nightly first, and is only now landing on stable.
I think relegating Prior art: |
@scottmcm not sure I entirely understand what you are trying to say, so let me to elaborate on my goals here: The single reason is that I want to shorten unimplemented to todo. Ideally, I wish it was named todo from the start. However, we already have unimplemented, so we need to do something about it. One choice is to deprecate, another choice is to repurpose. The PR description went with repurposing, because, after grepping rust-lang/rust, I’ve noticed that it already is being used in the C#’s not supported sense. |
I'm entirely in favor of this. |
☔ The latest upstream changes (presumably #56275) made this pull request unmergeable. Please resolve the merge conflicts. |
/// | ||
/// # Panics | ||
/// | ||
/// This will always [panic!](macro.panic.html) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this say "panics"?
src/libcore/macros.rs
Outdated
/// | ||
/// 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 `unimplemented!`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This says to use the unimplemented
macro.
Renamed to |
I'm not sure |
This comment has been minimized.
This comment has been minimized.
An all-caps macro strikes me as a large enough digression from Rust style conventions to be immediately confusing to a reader. |
Don't have an opinion about which capitalization is better, will leave that to libs team to decide. Both Kotlin & Go decided to change naming convention for this macro though. |
There is some precedent: TODO in comments tends to be all caps. |
TODO in comments is not a macro invocation. |
I know, but it is related to TODOs... |
This comment has been minimized.
This comment has been minimized.
I am sympathetic to At the same time I agree with @scottmcm in #56348 (comment) and would prefer not to see I am pretty ambivalent but probably leaning against making this change -- meaning I would continue to use Regarding capitalization, I would advise against weighing Go as precedent. They were hamstrung by requiring a capital first letter on public functions, at which point |
rebased and created&filled the tracking issue |
@matklad This looks good and I'd like to request just one more change: add a sentence to the docs of both |
I think we should only change |
that makes sense to me @bors r+ |
📌 Commit c11b37af0ec9d0b5dbe5bed7361740e23cfcd4b4 has been approved by |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The use-case of `todo!()` macro is to be a much easier to type alternative to `unimplemented!()` macro.
@bors r+ |
📌 Commit 9d408d9 has been approved by |
@bors rollup |
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>
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>
Rollup of 11 pull requests Successful merges: - #56348 (Add todo!() macro) - #57729 (extra testing of how NLL handles wildcard type `_`) - #57847 (dbg!() without parameters) - #58778 (Implement ExactSizeIterator for ToLowercase and ToUppercase) - #58812 (Clarify distinction between floor() and trunc()) - #58939 (Fix a tiny error in documentation of std::pin.) - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation) - #59252 (add self to mailmap) - #59275 (Replaced self-reflective explicit types with clearer `Self` or `Self::…` in stdlib docs) - #59280 (Stabilize refcell_map_split feature) - #59290 (Run branch cleanup after copy prop) Failed merges: r? @ghost
Just going to leave a link to #39930 and rust-lang/rfcs#1911 here so that we maintain the breadcrumbs for people digging later on. |
I cannot understand why people think that “todo” is “panic”. Historically //TODO is a note that does not violate your program. But this discussion said todo! have to break your program. #[macro_export]
#[unstable(feature = "todo_macro", issue = "59277")]
macro_rules! todo {
() => (panic!("not yet implemented"));
($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
} We have a lot of important RFC. Let's leave the |
The convention that this is making easier is not unprecedented. A lot of development flows say that In addition, this makes no change to The purpose of this is more to provide |
easy shouldn't be confusing
A lot of people say that earth is flat. But https://en.wikipedia.org/wiki/Comment_(computer_programming) says "TODO – something to be done."
todo! mustn't raise an error.
If you want to see a shorter version than |
The primary use-case of
todo!()
macro is to be a much easier to typealternative to
unimplemented!()
macro.EDIT: hide unpopular proposal about re-purposing unimplemented
With the addition of TODO, you have three nuanced choices for a
!
-returning macro (in addition to a good-old panic we all love):Here's a rough guideline what each one means:
todo
: use it during development, as a "hole" or placeholder. Itmight 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 guaranteethat some situation can not happen. If you use a library and hit
unreachable!()
in the library's code, it's definitely a bug in thelibrary. 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 tohandle 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, thoughit 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 usuallysignifies a clunky, eyebrow-rising API.