Skip to content

Commit 8e80866

Browse files
authored
Merge pull request #3178 from ms2300/bad_unwrap
Fix for bad get unwrap suggestion
2 parents 6b17ce4 + 523ba2a commit 8e80866

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

clippy_lints/src/methods.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,22 +1426,33 @@ fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::
14261426
// Note: we don't want to lint `get_mut().unwrap` for HashMap or BTreeMap,
14271427
// because they do not implement `IndexMut`
14281428
let expr_ty = cx.tables.expr_ty(&get_args[0]);
1429+
let get_args_str = if get_args.len() > 1 {
1430+
snippet(cx, get_args[1].span, "_")
1431+
} else {
1432+
return; // not linting on a .get().unwrap() chain or variant
1433+
};
1434+
let needs_ref;
14291435
let caller_type = if derefs_to_slice(cx, &get_args[0], expr_ty).is_some() {
1436+
needs_ref = get_args_str.parse::<usize>().is_ok();
14301437
"slice"
14311438
} else if match_type(cx, expr_ty, &paths::VEC) {
1439+
needs_ref = get_args_str.parse::<usize>().is_ok();
14321440
"Vec"
14331441
} else if match_type(cx, expr_ty, &paths::VEC_DEQUE) {
1442+
needs_ref = get_args_str.parse::<usize>().is_ok();
14341443
"VecDeque"
14351444
} else if !is_mut && match_type(cx, expr_ty, &paths::HASHMAP) {
1445+
needs_ref = true;
14361446
"HashMap"
14371447
} else if !is_mut && match_type(cx, expr_ty, &paths::BTREEMAP) {
1448+
needs_ref = true;
14381449
"BTreeMap"
14391450
} else {
14401451
return; // caller is not a type that we want to lint
14411452
};
14421453

14431454
let mut_str = if is_mut { "_mut" } else { "" };
1444-
let borrow_str = if is_mut { "&mut " } else { "&" };
1455+
let borrow_str = if !needs_ref { "" } else if is_mut { "&mut " } else { "&" };
14451456
span_lint_and_sugg(
14461457
cx,
14471458
GET_UNWRAP,
@@ -1456,7 +1467,7 @@ fn lint_get_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr, get_args: &[hir::
14561467
"{}{}[{}]",
14571468
borrow_str,
14581469
snippet(cx, get_args[0].span, "_"),
1459-
snippet(cx, get_args[1].span, "_")
1470+
get_args_str
14601471
),
14611472
);
14621473
}

tests/ui/get_unwrap.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ fn main() {
4343
*some_btreemap.get_mut(&1).unwrap() = 'b';
4444
*false_positive.get_mut(0).unwrap() = 1;
4545
}
46+
47+
{ // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`
48+
let _ = some_vec.get(0..1).unwrap().to_vec();
49+
let _ = some_vec.get_mut(0..1).unwrap().to_vec();
50+
}
4651
}

tests/ui/get_unwrap.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,17 @@ error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and
6060
40 | *some_vecdeque.get_mut(0).unwrap() = 1;
6161
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_vecdeque[0]`
6262

63-
error: aborting due to 10 previous errors
63+
error: called `.get().unwrap()` on a Vec. Using `[]` is more clear and more concise
64+
--> $DIR/get_unwrap.rs:48:17
65+
|
66+
48 | let _ = some_vec.get(0..1).unwrap().to_vec();
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
68+
69+
error: called `.get_mut().unwrap()` on a Vec. Using `[]` is more clear and more concise
70+
--> $DIR/get_unwrap.rs:49:17
71+
|
72+
49 | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
73+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `some_vec[0..1]`
74+
75+
error: aborting due to 12 previous errors
6476

0 commit comments

Comments
 (0)