Skip to content

Commit 6331c94

Browse files
committed
include a ref if argument is not just a numeric literal
1 parent 3217f8a commit 6331c94

File tree

4 files changed

+84
-9
lines changed

4 files changed

+84
-9
lines changed

clippy_lints/src/methods/get_unwrap.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ pub(super) fn check<'tcx>(
2525
let get_args_str = snippet_with_applicability(cx, get_arg.span, "..", &mut applicability);
2626
let mut needs_ref;
2727
let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() {
28-
needs_ref = get_args_str.parse::<usize>().is_ok();
28+
needs_ref = true;
2929
"slice"
3030
} else if is_type_diagnostic_item(cx, expr_ty, sym::Vec) {
31-
needs_ref = get_args_str.parse::<usize>().is_ok();
31+
needs_ref = true;
3232
"Vec"
3333
} else if is_type_diagnostic_item(cx, expr_ty, sym::VecDeque) {
34-
needs_ref = get_args_str.parse::<usize>().is_ok();
34+
needs_ref = true;
3535
"VecDeque"
3636
} else if !is_mut && is_type_diagnostic_item(cx, expr_ty, sym::HashMap) {
3737
needs_ref = true;
@@ -45,16 +45,23 @@ pub(super) fn check<'tcx>(
4545

4646
let mut span = expr.span;
4747

48-
// Handle the case where the result is immediately dereferenced
49-
// by not requiring ref and pulling the dereference into the
50-
// suggestion.
48+
// Handle the case where the result is immediately dereferenced,
49+
// either directly be the user, or as a result of a method call or the like
50+
// by not requiring an explicit reference
5151
if_chain! {
5252
if needs_ref;
5353
if let Some(parent) = get_parent_expr(cx, expr);
54-
if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind;
54+
if let hir::ExprKind::Unary(hir::UnOp::Deref, _)
55+
| hir::ExprKind::MethodCall(..)
56+
| hir::ExprKind::Field(..)
57+
| hir::ExprKind::Index(..) = parent.kind;
5558
then {
59+
if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind {
60+
// if the user explicitly dereferences the result, we can adjust
61+
// the span to also include the deref part
62+
span = parent.span;
63+
}
5664
needs_ref = false;
57-
span = parent.span;
5865
}
5966
}
6067

tests/ui/get_unwrap.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,17 @@ fn main() {
6969
let _ = some_vec[0..1].to_vec();
7070
let _ = some_vec[0..1].to_vec();
7171
}
72+
issue9909();
73+
}
74+
fn issue9909() {
75+
let f = &[1, 2, 3];
76+
77+
let _x: &i32 = &f[1 + 2];
78+
// ^ include a borrow in the suggestion, even if the argument is not just a numeric literal
79+
80+
let _x = f[1 + 2].to_string();
81+
// ^ don't include a borrow here
82+
83+
let _x = f[1 + 2].abs();
84+
// ^ don't include a borrow here
7285
}

tests/ui/get_unwrap.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,17 @@ fn main() {
6969
let _ = some_vec.get(0..1).unwrap().to_vec();
7070
let _ = some_vec.get_mut(0..1).unwrap().to_vec();
7171
}
72+
issue9909();
73+
}
74+
fn issue9909() {
75+
let f = &[1, 2, 3];
76+
77+
let _x: &i32 = f.get(1 + 2).unwrap();
78+
// ^ include a borrow in the suggestion, even if the argument is not just a numeric literal
79+
80+
let _x = f.get(1 + 2).unwrap().to_string();
81+
// ^ don't include a borrow here
82+
83+
let _x = f.get(1 + 2).unwrap().abs();
84+
// ^ don't include a borrow here
7285
}

tests/ui/get_unwrap.stderr

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,47 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
187187
|
188188
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
189189

190-
error: aborting due to 26 previous errors
190+
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
191+
--> $DIR/get_unwrap.rs:77:20
192+
|
193+
LL | let _x: &i32 = f.get(1 + 2).unwrap();
194+
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `&f[1 + 2]`
195+
196+
error: used `unwrap()` on an `Option` value
197+
--> $DIR/get_unwrap.rs:77:20
198+
|
199+
LL | let _x: &i32 = f.get(1 + 2).unwrap();
200+
| ^^^^^^^^^^^^^^^^^^^^^
201+
|
202+
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
203+
204+
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
205+
--> $DIR/get_unwrap.rs:80:14
206+
|
207+
LL | let _x = f.get(1 + 2).unwrap().to_string();
208+
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `f[1 + 2]`
209+
210+
error: used `unwrap()` on an `Option` value
211+
--> $DIR/get_unwrap.rs:80:14
212+
|
213+
LL | let _x = f.get(1 + 2).unwrap().to_string();
214+
| ^^^^^^^^^^^^^^^^^^^^^
215+
|
216+
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
217+
218+
error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
219+
--> $DIR/get_unwrap.rs:83:14
220+
|
221+
LL | let _x = f.get(1 + 2).unwrap().abs();
222+
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `f[1 + 2]`
223+
224+
error: used `unwrap()` on an `Option` value
225+
--> $DIR/get_unwrap.rs:83:14
226+
|
227+
LL | let _x = f.get(1 + 2).unwrap().abs();
228+
| ^^^^^^^^^^^^^^^^^^^^^
229+
|
230+
= help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message
231+
232+
error: aborting due to 32 previous errors
191233

0 commit comments

Comments
 (0)