Skip to content

Reduce unreachable-code churn after todo!()#149543

Open
llogiq wants to merge 1 commit intorust-lang:mainfrom
llogiq:less-todo-unreachable-churn
Open

Reduce unreachable-code churn after todo!()#149543
llogiq wants to merge 1 commit intorust-lang:mainfrom
llogiq:less-todo-unreachable-churn

Conversation

@llogiq
Copy link
Copy Markdown
Contributor

@llogiq llogiq commented Dec 2, 2025

View all comments

This was prompted by a rant by /u/matthieum on /r/rust. The idea here is that while writing the code, either rust-analyzer or ourselves may insert todo!() at places we intend to implement later. Unfortunately, that marks all following code as unreachable, which will prompt some lint churn.

So to combat that, I modify the lint to check whether the unreachability stems from a todo!() macro and in this case omit the lint (by setting diverges to Diverges::WarnedAlways instead of Always(..)). Hopefully that makes the unreachable code lint less churn-y during development and improve the developer experience.

In lieu of the unreachable_code lint, this PR also adds a todo_macro_uses lint.

I inserted the check after when we already found some unreachable code, so perf shouldn't suffer too badly.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 2, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Dec 2, 2025

r? @fee1-dead

rustbot has assigned @fee1-dead.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@Kivooeo
Copy link
Copy Markdown
Member

Kivooeo commented Dec 2, 2025

Could you please also add a link to the Zulip discussion? It would help provide context.

Also, could you please add a test to demonstrate that it works?

&& self.expr_guaranteed_to_constitute_read_for_never(expr)
{
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
let diverges = if self.is_todo_macro(expr.span) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we find that this is too heavy on perf (which it would only be in macro-heavy crates where macros produce a lot of exprs of type !), we could first check that the expression has ExprKind::Call(path, [txt]) where path refers to core::panic::panic.

@iago-lito
Copy link
Copy Markdown
Contributor

Here is the zulip thread.

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 4, 2025

Also, could you please add a test to demonstrate that it works?

I added some code to the respective UI test. E.g. current rustc warns on todo!(); let _ = false.

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 5, 2025

r? @estebank

@rustbot rustbot assigned estebank and unassigned fee1-dead Dec 5, 2025
@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 310c17e to af403c6 Compare December 9, 2025 21:13
@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 12, 2025

Open question: Should I add some docs to the todo! macro to describe the behavior?

@iago-lito
Copy link
Copy Markdown
Contributor

iago-lito commented Dec 12, 2025

I'd personally be happy to read a line about it in the docs, although I would understand that someone steps forward and explains whether/why it'd be off-topic?

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 13, 2025

I'm unsure whether this is too cross-cutting a concern, which is why I'm asking.

OTOH, creating another PR just for one line of docs seems wasteful.

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 13, 2025

Perhaps something like:

/// The `unreachable_code` lint will ignore code after a `todo!()`. The code will
/// however still be marked as unreachable, which may
/// have effects on type and lifetime checks.

This implies that todo!() could still be in released code without the compiler giving a warning. Perhaps we should upstream clippy's todo lint next and make it warn by default in release mode?

Copy link
Copy Markdown
Member

@WaffleLapkin WaffleLapkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit hard to discover, but the right directory for the test is tests/ui/reachable

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move the test under a todo.rs there.



fn foo() {
todo!();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a test for when another macro expands to todo!?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! 👍

@rustbot rustbot assigned WaffleLapkin and unassigned estebank Dec 15, 2025
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 15, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Dec 15, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@WaffleLapkin
Copy link
Copy Markdown
Member

I think having different lints for debug/release is a bad idea, but mentioning this change in todo's docs is good. Either way, this needs T-lang approval, as this is a lint change. Please write a comment explaining the proposal to the language team and nominate this PR for them.

@WaffleLapkin WaffleLapkin added the S-waiting-on-t-lang Status: Awaiting decision from T-lang label Dec 15, 2025
@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from af403c6 to a79858c Compare December 15, 2025 14:29
@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 15, 2025

T-lang nomination

This PR makes the unreachable_code lint ignore code after the todo!() macro. The reasoning behind this is that todo!() is meant as a temporary shortcut while the code is unfinished, and various tools (e.g. rust-analyzer) will insert it at many places as a stand in for code to add, leading to a plethora of unhelpful lint messages, which some perhaps might even consider a false positive. So by avoiding linting unreachable code after todo!(), the user can concentrate on the things they should.

The downside is that a developer won't get any warning on a todo!(). There's a clippy lint against that, though, which we could upstream.

@tomassedovic tomassedovic added the I-lang-nominated Nominated for discussion during a lang team meeting. label Dec 15, 2025
@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Dec 15, 2025

@rustbot ready

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Dec 15, 2025
@rust-rfcbot rust-rfcbot added the disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. label Apr 1, 2026
@traviscross
Copy link
Copy Markdown
Contributor

traviscross commented Apr 1, 2026

@rfcbot concern please-rename-lint

(Filing this just to ensure the rename to todo_macro_calls.)

@RalfJung
Copy link
Copy Markdown
Member

RalfJung commented Apr 1, 2026

Please also update the PR description, it seems to be quite outdated at the moment.

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 5e3d4b0 to 19dc6dc Compare April 3, 2026 18:34
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 3, 2026

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a, @makai410

The Miri subtree was changed

cc @rust-lang/miri

Some changes occurred in compiler/rustc_sanitizers

cc @rcvalle

Some changes occurred in compiler/rustc_builtin_macros/src/autodiff.rs

cc @ZuseZ4

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Apr 3, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 3, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Apr 3, 2026

I think I fixed most errors in the tests and dogfooding of the lint. I have yet to rename it though.

@rust-log-analyzer

This comment has been minimized.

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 19dc6dc to 4c2b4fa Compare April 3, 2026 19:11
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 3, 2026

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 4c2b4fa to 9e26eae Compare April 3, 2026 19:30
@rust-log-analyzer

This comment has been minimized.

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 9e26eae to 2ebfbca Compare April 4, 2026 08:26
@llogiq llogiq requested a review from traviscross April 4, 2026 08:27
@llogiq llogiq dismissed traviscross’s stale review April 4, 2026 08:28

I removed the crate in question

@rust-log-analyzer

This comment has been minimized.

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from 2ebfbca to ee994f8 Compare April 4, 2026 09:23
@rust-log-analyzer

This comment has been minimized.

@llogiq llogiq force-pushed the less-todo-unreachable-churn branch from ee994f8 to d626981 Compare April 4, 2026 11:00
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 4, 2026

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job pr-check-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
    ::: src/tools/clippy/clippy_utils/src/ast_utils/mod.rs:1023:65
     |
1023 |         (AttrItemKind::Parsed(_l), AttrItemKind::Parsed(_r)) => todo!(),
     |                                                                 ------- in this macro invocation
     |
     = note: `#[warn(todo_macro_calls)]` on by default

[RUSTC-TIMING] tracing_error test:false 0.199
[RUSTC-TIMING] icu_properties test:false 2.446
    Checking idna_adapter v1.2.1
[RUSTC-TIMING] idna_adapter test:false 0.127

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Apr 4, 2026

I'm adding a boatload of allow annotations here, including on subprojects. At this point I wonder whether we should allow the lint in bootstrap somehow...

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Apr 4, 2026

☔ The latest upstream changes (presumably #154773) made this pull request unmergeable. Please resolve the merge conflicts.

@camsteffen
Copy link
Copy Markdown
Contributor

I'm a bit unsure about the lint being warn by default. I think I would prefer it allow by default and I'd maybe turn it on for CI builds. (And I generally expect dev tools to favor the local development experience by default.) The mere presence of the macro in my code/diff, and the panicking behavior, is signal enough for me. But seeing the warning on every check build can be noisy when I'm working on something else in the moment.

Turning the lint on by default makes the compiler more loud by default since IIUC most todo uses don't have unreachable code following it. On the other hand, allow by default makes the compiler less loud, but I think the delta is smaller.

@llogiq
Copy link
Copy Markdown
Contributor Author

llogiq commented Apr 4, 2026

Yeah, I believe we settled on warn by default to avoid people running into unwanted panics. But I agree that it probably should be allow by default (I wish we had an option of making "allow in debug, warn on release" standard behavior).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rustdoc-json Area: Rustdoc JSON backend disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-explicit_tail_calls `#![feature(explicit_tail_calls)]` I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang PG-exploit-mitigations Project group: Exploit mitigations proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-t-lang Status: Awaiting decision from T-lang T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.