@@ -73,7 +73,7 @@ declare_clippy_lint! {
7373 /// **Known problems:** None.
7474 ///
7575 /// **Example:**
76- /// Using unwrap on an `Option `:
76+ /// Using unwrap on an `Result `:
7777 ///
7878 /// ```rust
7979 /// let res: Result<usize, ()> = Ok(1);
@@ -91,6 +91,65 @@ declare_clippy_lint! {
9191 "using `Result.unwrap()`, which might be better handled"
9292}
9393
94+ declare_clippy_lint ! {
95+ /// **What it does:** Checks for `.expect()` calls on `Option`s.
96+ ///
97+ /// **Why is this bad?** Usually it is better to handle the `None` case. Still,
98+ /// for a lot of quick-and-dirty code, `expect` is a good choice, which is why
99+ /// this lint is `Allow` by default.
100+ ///
101+ /// **Known problems:** None.
102+ ///
103+ /// **Example:**
104+ ///
105+ /// Using expect on an `Option`:
106+ ///
107+ /// ```rust
108+ /// let opt = Some(1);
109+ /// opt.expect("one");
110+ /// ```
111+ ///
112+ /// Better:
113+ ///
114+ /// ```ignore
115+ /// let opt = Some(1);
116+ /// opt?;
117+ /// # Some::<()>(())
118+ /// ```
119+ pub OPTION_EXPECT_USED ,
120+ restriction,
121+ "using `Option.expect()`, which might be better handled"
122+ }
123+
124+ declare_clippy_lint ! {
125+ /// **What it does:** Checks for `.expect()` calls on `Result`s.
126+ ///
127+ /// **Why is this bad?** `result.expect()` will let the thread panic on `Err`
128+ /// values. Normally, you want to implement more sophisticated error handling,
129+ /// and propagate errors upwards with `try!`.
130+ ///
131+ /// **Known problems:** None.
132+ ///
133+ /// **Example:**
134+ /// Using expect on an `Result`:
135+ ///
136+ /// ```rust
137+ /// let res: Result<usize, ()> = Ok(1);
138+ /// res.expect("one");
139+ /// ```
140+ ///
141+ /// Better:
142+ ///
143+ /// ```
144+ /// let res: Result<usize, ()> = Ok(1);
145+ /// res?;
146+ /// # Ok::<(), ()>(())
147+ /// ```
148+ pub RESULT_EXPECT_USED ,
149+ restriction,
150+ "using `Result.expect()`, which might be better handled"
151+ }
152+
94153declare_clippy_lint ! {
95154 /// **What it does:** Checks for methods that should live in a trait
96155 /// implementation of a `std` trait (see [llogiq's blog
@@ -1037,6 +1096,8 @@ declare_clippy_lint! {
10371096declare_lint_pass ! ( Methods => [
10381097 OPTION_UNWRAP_USED ,
10391098 RESULT_UNWRAP_USED ,
1099+ OPTION_EXPECT_USED ,
1100+ RESULT_EXPECT_USED ,
10401101 SHOULD_IMPLEMENT_TRAIT ,
10411102 WRONG_SELF_CONVENTION ,
10421103 WRONG_PUB_SELF_CONVENTION ,
@@ -1095,6 +1156,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
10951156 [ "unwrap" , "get_mut" ] => lint_get_unwrap ( cx, expr, arg_lists[ 1 ] , true ) ,
10961157 [ "unwrap" , ..] => lint_unwrap ( cx, expr, arg_lists[ 0 ] ) ,
10971158 [ "expect" , "ok" ] => lint_ok_expect ( cx, expr, arg_lists[ 1 ] ) ,
1159+ [ "expect" , ..] => lint_expect ( cx, expr, arg_lists[ 0 ] ) ,
10981160 [ "unwrap_or" , "map" ] => option_map_unwrap_or:: lint ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
10991161 [ "unwrap_or_else" , "map" ] => lint_map_unwrap_or_else ( cx, expr, arg_lists[ 1 ] , arg_lists[ 0 ] ) ,
11001162 [ "map_or" , ..] => lint_map_or_none ( cx, expr, arg_lists[ 0 ] ) ,
@@ -2063,6 +2125,31 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, unwrap_args: &[hir::E
20632125 }
20642126}
20652127
2128+ /// lint use of `expect()` for `Option`s and `Result`s
2129+ fn lint_expect ( cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr , expect_args : & [ hir:: Expr ] ) {
2130+ let obj_ty = walk_ptrs_ty ( cx. tables . expr_ty ( & expect_args[ 0 ] ) ) ;
2131+
2132+ let mess = if match_type ( cx, obj_ty, & paths:: OPTION ) {
2133+ Some ( ( OPTION_EXPECT_USED , "an Option" , "None" ) )
2134+ } else if match_type ( cx, obj_ty, & paths:: RESULT ) {
2135+ Some ( ( RESULT_EXPECT_USED , "a Result" , "Err" ) )
2136+ } else {
2137+ None
2138+ } ;
2139+
2140+ if let Some ( ( lint, kind, none_value) ) = mess {
2141+ span_lint (
2142+ cx,
2143+ lint,
2144+ expr. span ,
2145+ & format ! (
2146+ "used expect() on {} value. If this value is an {} it will panic" ,
2147+ kind, none_value
2148+ ) ,
2149+ ) ;
2150+ }
2151+ }
2152+
20662153/// lint use of `ok().expect()` for `Result`s
20672154fn lint_ok_expect ( cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr , ok_args : & [ hir:: Expr ] ) {
20682155 if_chain ! {
0 commit comments