new lint for Option.unwrap() and Result.unwrap()

The latter is set to Allow by default (fixes #24)
This commit is contained in:
Georg Brandl 2015-08-11 20:53:50 +02:00
parent cf96042c65
commit 2bcc151888
3 changed files with 54 additions and 0 deletions

View file

@ -29,6 +29,7 @@ pub mod collapsible_if;
pub mod unicode;
pub mod utils;
pub mod strings;
pub mod methods;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
@ -55,6 +56,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_lint_pass(box unicode::Unicode as LintPassObject);
reg.register_lint_pass(box strings::StringAdd as LintPassObject);
reg.register_lint_pass(box misc::NeedlessReturn as LintPassObject);
reg.register_lint_pass(box methods::MethodsPass as LintPassObject);
reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
misc::SINGLE_MATCH, misc::STR_TO_STRING,
@ -77,5 +79,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
strings::STRING_ADD_ASSIGN,
misc::NEEDLESS_RETURN,
misc::MODULO_ONE,
methods::OPTION_UNWRAP_USED,
methods::RESULT_UNWRAP_USED,
]);
}

39
src/methods.rs Normal file
View file

@ -0,0 +1,39 @@
use syntax::ast::*;
use rustc::lint::{Context, LintPass, LintArray};
use rustc::middle::ty;
use utils::{span_lint, match_def_path, walk_ptrs_ty};
#[derive(Copy,Clone)]
pub struct MethodsPass;
declare_lint!(pub OPTION_UNWRAP_USED, Warn,
"Warn on using unwrap() on an Option value");
declare_lint!(pub RESULT_UNWRAP_USED, Allow,
"Warn on using unwrap() on a Result value");
impl LintPass for MethodsPass {
fn get_lints(&self) -> LintArray {
lint_array!(OPTION_UNWRAP_USED, RESULT_UNWRAP_USED)
}
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
if let ExprMethodCall(ref ident, _, ref args) = expr.node {
if ident.node.name == "unwrap" {
if let ty::TyEnum(did, _) = walk_ptrs_ty(cx.tcx.expr_ty(&*args[0])).sty {
if match_def_path(cx, did.did, &["core", "option", "Option"]) {
span_lint(cx, OPTION_UNWRAP_USED, expr.span,
"used unwrap() on an Option value. If you don't want \
to handle the None case gracefully, consider using
expect() to provide a better panic message.");
}
else if match_def_path(cx, did.did, &["core", "result", "Result"]) {
span_lint(cx, RESULT_UNWRAP_USED, expr.span,
"used unwrap() on a Result value. Graceful handling \
of Err values is preferred.");
}
}
}
}
}
}

11
tests/compile-fail/methods.rs Executable file
View file

@ -0,0 +1,11 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(option_unwrap_used, result_unwrap_used)]
fn main() {
let opt = Some(0);
let _ = opt.unwrap(); //~ERROR
let res: Result<i32, ()> = Ok(0);
let _ = res.unwrap(); //~ERROR
}