Skip to content

Commit 1827791

Browse files
committed
add more negative test cases, replace an unnecessary def path with diag item
1 parent ea2f087 commit 1827791

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

clippy_lints/src/unconditional_recursion.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2-
use clippy_utils::{expr_or_init, fn_def_id_with_node_args, get_trait_def_id, path_def_id};
3-
use itertools::Itertools;
2+
use clippy_utils::{expr_or_init, fn_def_id_with_node_args, path_def_id};
43
use rustc_ast::BinOpKind;
54
use rustc_data_structures::fx::FxHashMap;
65
use rustc_hir as hir;
@@ -311,10 +310,9 @@ where
311310
}
312311

313312
impl UnconditionalRecursion {
314-
#[allow(clippy::unnecessary_def_path)]
315313
fn init_default_impl_for_type_if_needed(&mut self, cx: &LateContext<'_>) {
316314
if self.default_impl_for_type.is_empty()
317-
&& let Some(default_trait_id) = get_trait_def_id(cx, &["core", "default", "Default"])
315+
&& let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
318316
{
319317
let impls = cx.tcx.trait_impls_of(default_trait_id);
320318
for (ty, impl_def_ids) in impls.non_blanket_impls() {
@@ -409,7 +407,8 @@ fn check_from(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId
409407
// which calls back into our `From::from` again (`Into` is not specializable).
410408
// rustc's unconditional_recursion already catches calling `From::from` directly
411409
if let Some((fn_def_id, node_args)) = fn_def_id_with_node_args(cx, expr)
412-
&& let Some((s1, s2)) = node_args.iter().filter_map(ty::GenericArg::as_type).collect_tuple()
410+
&& let [s1, s2] = **node_args
411+
&& let (Some(s1), Some(s2)) = (s1.as_type(), s2.as_type())
413412
&& let Some(trait_def_id) = cx.tcx.trait_of_item(fn_def_id)
414413
&& cx.tcx.is_diagnostic_item(sym::Into, trait_def_id)
415414
&& get_impl_trait_def_id(cx, method_def_id) == cx.tcx.get_diagnostic_item(sym::From)

tests/ui/unconditional_recursion.rs

+26
Original file line numberDiff line numberDiff line change
@@ -372,4 +372,30 @@ impl<'a> From<BadFromTy2<'a>> for BadIntoTy2<'static> {
372372
}
373373
}
374374

375+
// Different Into impl (<i16 as Into<i32>>), so no infinite recursion
376+
struct BadFromTy3;
377+
impl From<BadFromTy3> for i32 {
378+
fn from(f: BadFromTy3) -> Self {
379+
Into::into(1i16)
380+
}
381+
}
382+
383+
// A conditional return that ends the recursion
384+
struct BadFromTy4;
385+
impl From<BadFromTy4> for i32 {
386+
fn from(f: BadFromTy4) -> Self {
387+
if true {
388+
return 42;
389+
}
390+
f.into()
391+
}
392+
}
393+
394+
// Types differ in refs, don't lint
395+
impl From<&BadFromTy4> for i32 {
396+
fn from(f: &BadFromTy4) -> Self {
397+
BadFromTy4.into()
398+
}
399+
}
400+
375401
fn main() {}

0 commit comments

Comments
 (0)