Skip to content

Commit 17f7047

Browse files
committed
Only return DefIds to Fn-like definitions in clippy_utils::fn_def_id
1 parent bc4d39e commit 17f7047

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed

clippy_utils/src/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,17 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
19161916
..
19171917
},
19181918
..,
1919-
) => cx.typeck_results().qpath_res(qpath, *path_hir_id).opt_def_id(),
1919+
) => {
1920+
// Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or
1921+
// deref to fn pointers, dyn Fn, impl Fn - #8850
1922+
if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =
1923+
cx.typeck_results().qpath_res(qpath, *path_hir_id)
1924+
{
1925+
Some(id)
1926+
} else {
1927+
None
1928+
}
1929+
},
19201930
_ => None,
19211931
}
19221932
}

tests/ui/crashes/ice-8850.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
fn fn_pointer_static() -> usize {
2+
static FN: fn() -> usize = || 1;
3+
let res = FN() + 1;
4+
res
5+
}
6+
7+
fn fn_pointer_const() -> usize {
8+
const FN: fn() -> usize = || 1;
9+
let res = FN() + 1;
10+
res
11+
}
12+
13+
fn deref_to_dyn_fn() -> usize {
14+
struct Derefs;
15+
impl std::ops::Deref for Derefs {
16+
type Target = dyn Fn() -> usize;
17+
18+
fn deref(&self) -> &Self::Target {
19+
&|| 2
20+
}
21+
}
22+
static FN: Derefs = Derefs;
23+
let res = FN() + 1;
24+
res
25+
}
26+
27+
fn main() {}

tests/ui/crashes/ice-8850.stderr

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
error: returning the result of a `let` binding from a block
2+
--> $DIR/ice-8850.rs:4:5
3+
|
4+
LL | let res = FN() + 1;
5+
| ------------------- unnecessary `let` binding
6+
LL | res
7+
| ^^^
8+
|
9+
= note: `-D clippy::let-and-return` implied by `-D warnings`
10+
help: return the expression directly
11+
|
12+
LL ~
13+
LL ~ FN() + 1
14+
|
15+
16+
error: returning the result of a `let` binding from a block
17+
--> $DIR/ice-8850.rs:10:5
18+
|
19+
LL | let res = FN() + 1;
20+
| ------------------- unnecessary `let` binding
21+
LL | res
22+
| ^^^
23+
|
24+
help: return the expression directly
25+
|
26+
LL ~
27+
LL ~ FN() + 1
28+
|
29+
30+
error: returning the result of a `let` binding from a block
31+
--> $DIR/ice-8850.rs:24:5
32+
|
33+
LL | let res = FN() + 1;
34+
| ------------------- unnecessary `let` binding
35+
LL | res
36+
| ^^^
37+
|
38+
help: return the expression directly
39+
|
40+
LL ~
41+
LL ~ FN() + 1
42+
|
43+
44+
error: aborting due to 3 previous errors
45+

0 commit comments

Comments
 (0)