diff options
| author | Alex Macleod <alex@macleod.io> | 2022-05-26 14:21:09 +0000 |
|---|---|---|
| committer | Alex Macleod <alex@macleod.io> | 2022-05-26 14:35:19 +0000 |
| commit | 17f70478116d3b77783db2ed6453697a77a7d769 (patch) | |
| tree | e3563f1c210573dc3b2cf32693c9e8723b9aaf8a | |
| parent | bc4d39e5fea64970dded1e6d2132d41435c0ef24 (diff) | |
| download | rust-17f70478116d3b77783db2ed6453697a77a7d769.tar.gz rust-17f70478116d3b77783db2ed6453697a77a7d769.zip | |
Only return DefIds to Fn-like definitions in clippy_utils::fn_def_id
| -rw-r--r-- | clippy_utils/src/lib.rs | 12 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-8850.rs | 27 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-8850.stderr | 45 |
3 files changed, 83 insertions, 1 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index adb37cc9d75..b8a80d4adc3 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -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, } } diff --git a/tests/ui/crashes/ice-8850.rs b/tests/ui/crashes/ice-8850.rs new file mode 100644 index 00000000000..f2747ab2239 --- /dev/null +++ b/tests/ui/crashes/ice-8850.rs @@ -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() {} diff --git a/tests/ui/crashes/ice-8850.stderr b/tests/ui/crashes/ice-8850.stderr new file mode 100644 index 00000000000..620fd1edaf7 --- /dev/null +++ b/tests/ui/crashes/ice-8850.stderr @@ -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 + |
