Skip to content

Commit

Permalink
new lint for Option.unwrap() and Result.unwrap()
Browse files Browse the repository at this point in the history
The latter is set to Allow by default.  Issue rust-lang#24
  • Loading branch information
birkenfeld committed Aug 11, 2015
1 parent daca92c commit 69c13f9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub mod collapsible_if;
pub mod unicode;
pub mod utils;
pub mod strings;
pub mod unwrap;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
Expand All @@ -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 unwrap::UnwrapPass as LintPassObject);

reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
misc::SINGLE_MATCH, misc::STR_TO_STRING,
Expand All @@ -77,5 +79,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
strings::STRING_ADD_ASSIGN,
misc::NEEDLESS_RETURN,
misc::MODULO_ONE,
unwrap::OPTION_UNWRAP_USED,
unwrap::RESULT_UNWRAP_USED,
]);
}
40 changes: 40 additions & 0 deletions src/unwrap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use syntax::ast::*;
use rustc::lint::{Context, LintPass, LintArray};
use rustc::middle::ty;

use utils::{span_lint, match_def_path, walk_ty};

#[derive(Copy,Clone)]
pub struct UnwrapPass;

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 UnwrapPass {
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" {
return;
}
if let ty::TyEnum(did, _) = walk_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 changes: 11 additions & 0 deletions tests/compile-fail/unwrap.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 69c13f9

Please sign in to comment.