Skip to content

Commit a79858c

Browse files
committed
reduce unreachable-code churn after todo!()
1 parent 47cd712 commit a79858c

5 files changed

Lines changed: 84 additions & 2 deletions

File tree

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
322322
if self.try_structurally_resolve_type(expr.span, ty).is_never()
323323
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
324324
{
325-
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
325+
let diverges = if self.tcx.is_expanded_by(expr.span, sym::todo_macro) {
326+
// We don't warn for `todo!()` that diverges to avoid flooding the
327+
// user with warnings while they are still working on their code.
328+
Diverges::WarnedAlways
329+
} else {
330+
Diverges::always(expr.span)
331+
};
332+
self.diverges.set(self.diverges.get() | diverges);
326333
}
327334

328335
// Record the type, which applies it effects.

compiler/rustc_middle/src/ty/context.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,21 @@ impl<'tcx> TyCtxt<'tcx> {
21312131
None => Err(VarError::NotPresent),
21322132
}
21332133
}
2134+
2135+
/// Returns whether this context was expanded by the macro with the given name.
2136+
pub fn is_expanded_by(self, span: Span, mac: Symbol) -> bool {
2137+
let mut ctxt = span.ctxt();
2138+
while !ctxt.is_root() {
2139+
let data = ctxt.outer_expn_data();
2140+
if let Some(def_id) = data.macro_def_id
2141+
&& self.is_diagnostic_item(mac, def_id)
2142+
{
2143+
return true;
2144+
}
2145+
ctxt = data.call_site.ctxt();
2146+
}
2147+
false
2148+
}
21342149
}
21352150

21362151
impl<'tcx> TyCtxtAt<'tcx> {

library/core/src/macros/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,10 @@ macro_rules! unimplemented {
812812
/// an intent of implementing the functionality later and the message is "not yet
813813
/// implemented", `unimplemented!` makes no such claims. Its message is "not implemented".
814814
///
815-
/// Also, some IDEs will mark `todo!`s.
815+
/// Also, some IDEs will mark `todo!`s. Furthermore, the `unreachable_code` lint will
816+
/// not warn on code that is unreachable because of a `todo!()` to reduce unhelpful
817+
/// messages. The code will however still be marked as unreachable, which may have an
818+
/// effect on type and lifetime checks.
816819
///
817820
/// # Panics
818821
///

tests/ui/reachable/todo.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//@ check-pass
2+
//@ edition: 2018
3+
4+
#![allow(unused)]
5+
#![warn(unreachable_code)]
6+
7+
macro_rules! later {
8+
() => { todo!() };
9+
}
10+
11+
fn foo() {
12+
todo!();
13+
let this_is_unreachable = 1;
14+
}
15+
16+
fn bar() {
17+
panic!("This is really unreachable");
18+
let really_unreachable = true;
19+
//~^ WARNING: unreachable
20+
}
21+
22+
fn baz() -> bool {
23+
if true {
24+
todo!();
25+
false
26+
} else if todo!() {
27+
true
28+
} else {
29+
later!();
30+
false
31+
}
32+
}
33+
34+
fn main() {
35+
foo();
36+
bar();
37+
if baz() {
38+
todo!();
39+
}
40+
let this_is_reachable = 1;
41+
}

tests/ui/reachable/todo.stderr

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
warning: unreachable statement
2+
--> $DIR/todo.rs:18:5
3+
|
4+
LL | panic!("This is really unreachable");
5+
| ------------------------------------ any code following this expression is unreachable
6+
LL | let really_unreachable = true;
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
8+
|
9+
note: the lint level is defined here
10+
--> $DIR/todo.rs:5:9
11+
|
12+
LL | #![warn(unreachable_code)]
13+
| ^^^^^^^^^^^^^^^^
14+
15+
warning: 1 warning emitted
16+

0 commit comments

Comments
 (0)