Skip to content

Commit

Permalink
[useless_conversion]: fix FP in macro and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Jul 2, 2023
1 parent c01bec6 commit 3c67feb
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
12 changes: 12 additions & 0 deletions clippy_lints/src/useless_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -
(expr, depth)
}

/// Checks if the given `expr` is an argument of a macro invocation.
/// This is a slow-ish operation, so consider calling this late
/// to avoid slowing down the lint in the happy path when not emitting a warning
fn is_macro_argument(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
if let Some(parent) = get_parent_expr(cx, expr) {
parent.span.from_expansion() || is_macro_argument(cx, parent)
} else {
false
}
}

#[expect(clippy::too_many_lines)]
impl<'tcx> LateLintPass<'tcx> for UselessConversion {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
Expand Down Expand Up @@ -174,6 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
&& let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos))
&& let ty::Param(param) = into_iter_param.kind()
&& let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index)
&& !is_macro_argument(cx, e)
{
// Get the "innermost" `.into_iter()` call, e.g. given this expression:
// `foo.into_iter().into_iter()`
Expand Down
19 changes: 19 additions & 0 deletions tests/ui/crashes/ice-11065.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![warn(clippy::useless_conversion)]

use std::iter::FromIterator;
use std::option::IntoIter as OptionIter;

fn eq<T: Eq>(a: T, b: T) -> bool {
a == b
}

macro_rules! tests {
($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({
const C: $ty = $expr;
assert!(eq(C($($test),*), $expr($($test),*)));
})+})
}

tests! {
FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
}

0 comments on commit 3c67feb

Please sign in to comment.