Skip to content

Only return DefIds to Fn-like definitions in clippy_utils::fn_def_id #8896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,17 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
..
},
..,
) => cx.typeck_results().qpath_res(qpath, *path_hir_id).opt_def_id(),
) => {
// Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or
// deref to fn pointers, dyn Fn, impl Fn - #8850
if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =
cx.typeck_results().qpath_res(qpath, *path_hir_id)
{
Some(id)
} else {
None
}
},
_ => None,
}
}
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/crashes/ice-8850.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
fn fn_pointer_static() -> usize {
static FN: fn() -> usize = || 1;
let res = FN() + 1;
res
}

fn fn_pointer_const() -> usize {
const FN: fn() -> usize = || 1;
let res = FN() + 1;
res
}

fn deref_to_dyn_fn() -> usize {
struct Derefs;
impl std::ops::Deref for Derefs {
type Target = dyn Fn() -> usize;

fn deref(&self) -> &Self::Target {
&|| 2
}
}
static FN: Derefs = Derefs;
let res = FN() + 1;
res
}

fn main() {}
45 changes: 45 additions & 0 deletions tests/ui/crashes/ice-8850.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
error: returning the result of a `let` binding from a block
--> $DIR/ice-8850.rs:4:5
|
LL | let res = FN() + 1;
| ------------------- unnecessary `let` binding
LL | res
| ^^^
|
= note: `-D clippy::let-and-return` implied by `-D warnings`
help: return the expression directly
|
LL ~
LL ~ FN() + 1
|

error: returning the result of a `let` binding from a block
--> $DIR/ice-8850.rs:10:5
|
LL | let res = FN() + 1;
| ------------------- unnecessary `let` binding
LL | res
| ^^^
|
help: return the expression directly
|
LL ~
LL ~ FN() + 1
|

error: returning the result of a `let` binding from a block
--> $DIR/ice-8850.rs:24:5
|
LL | let res = FN() + 1;
| ------------------- unnecessary `let` binding
LL | res
| ^^^
|
help: return the expression directly
|
LL ~
LL ~ FN() + 1
|

error: aborting due to 3 previous errors