Skip to content

Commit af403c6

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

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_session::parse::feature_err;
3333
use rustc_span::edit_distance::find_best_match_for_name;
3434
use rustc_span::hygiene::DesugaringKind;
3535
use rustc_span::source_map::Spanned;
36-
use rustc_span::{Ident, Span, Symbol, kw, sym};
36+
use rustc_span::{Ident, Span, Symbol, SyntaxContext, kw, sym};
3737
use rustc_trait_selection::infer::InferCtxtExt;
3838
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
3939
use tracing::{debug, instrument, trace};
@@ -220,6 +220,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
220220
self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
221221
}
222222

223+
fn is_todo_macro(&self, span: Span) -> bool {
224+
let mut ctxt = span.ctxt();
225+
while ctxt != SyntaxContext::root() {
226+
let data = ctxt.outer_expn_data();
227+
if let Some(def_id) = data.macro_def_id
228+
&& self.tcx.is_diagnostic_item(sym::todo_macro, def_id)
229+
{
230+
return true;
231+
}
232+
ctxt = data.call_site.ctxt();
233+
}
234+
false
235+
}
236+
223237
/// Check an expr with an expectation type which may be used to eagerly
224238
/// guide inference when evaluating that expr.
225239
#[instrument(skip(self, expr), level = "debug")]
@@ -322,7 +336,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
322336
if self.try_structurally_resolve_type(expr.span, ty).is_never()
323337
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
324338
{
325-
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
339+
let diverges = if self.is_todo_macro(expr.span) {
340+
// We don't warn for `todo!()` that diverges to avoid flooding the
341+
// user with warnings while they are still working on their code.
342+
Diverges::WarnedAlways
343+
} else {
344+
Diverges::always(expr.span)
345+
};
346+
self.diverges.set(self.diverges.get() | diverges);
326347
}
327348

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

tests/ui/lint/unreachable_code.rs

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

0 commit comments

Comments
 (0)