Skip to content
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

Allow unused variables with todo! #79850

42 changes: 40 additions & 2 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@
use self::LiveNodeKind::*;
use self::VarKind::*;

use rustc_ast::InlineAsmOptions;
use rustc_ast::{InlineAsmOptions, LitKind, StrStyle};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def::*;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet};
use rustc_hir::{Expr, ExprKind, HirId, HirIdMap, HirIdSet, QPath};
use rustc_index::vec::IndexVec;
use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
Expand Down Expand Up @@ -329,6 +329,44 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
}
}

// Allow todo! macro
/*
Skips checking for unused variables when the trailing expression
of the body is core::panicking::panic("not yet implemented"), ie
as emitted by todo!().

# Example

fn foo(x: i32) {
// arbitrary code
todo!()
}
*/
if let ExprKind::Block(block, _) = &body.value.kind {
if let Some(expr) = block.expr {
if let ExprKind::Call(call, [arg]) = expr.kind {
if let ExprKind::Path(QPath::Resolved(_, path)) = call.kind {
if matches!(&path.res, Res::Def(DefKind::Fn, _)) {
// FIXME: Better way of extracting literal
let debug = format!("{:?}", &path.res);
if (debug.contains("std[") || debug.contains("core["))
&& debug.contains("]::panicking::panic)")
{
if let ExprKind::Lit(spanned) = &arg.kind {
if let LitKind::Str(symbol, StrStyle::Cooked) = spanned.node {
// FIXME: Better way of matching symbol
if &*symbol.as_str() == "not yet implemented" {
return;
}
}
}
}
}
}
}
}
}

if let Some(captures) = maps.tcx.typeck(local_def_id).closure_captures.get(&def_id) {
for &var_hir_id in captures.keys() {
let var_name = maps.tcx.hir().name(var_hir_id);
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/unused/allow-unused-variables-with-todo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// check-pass

#[deny(unused_variables)]
fn foo(x: i32, y: i32) -> i32 {
let z = x + y;
todo!()
}

fn main() {
foo(0, 1);
}