From 98b11c8f7bfd7efd5044b6011ba1f4d71f46b223 Mon Sep 17 00:00:00 2001 From: bors Date: Wed, 5 May 2021 17:33:46 +0000 Subject: [PATCH] Auto merge of #7170 - flip1995:revert_drop_order, r=llogiq Fix stack overflow issue in `redundant_pattern_matching` Fixes #7169 ~~cc `@Jarcho` Since tomorrow is release day and we need to get this also fixed in beta, I'll just revert the PR instead of looking into the root issue. Your changes are good, so if you have an idea what could cause this stack overflow and know how to fix it, please open a PR that reverts this revert with a fix.~~ r? `@llogiq` changelog: none (fixes stack overflow, but this was introduced in this release cycle) --- clippy_lints/src/matches.rs | 16 ++++++++++++---- tests/ui/crashes/ice-7169.rs | 9 +++++++++ tests/ui/crashes/ice-7169.stderr | 10 ++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tests/ui/crashes/ice-7169.rs create mode 100644 tests/ui/crashes/ice-7169.stderr diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 13b2a834b0a..50e2898bdaa 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1712,6 +1712,7 @@ mod redundant_pattern_match { use clippy_utils::{is_lang_ctor, is_qpath_def_path, is_trait_method, paths}; use if_chain::if_chain; use rustc_ast::ast::LitKind; + use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; use rustc_hir::{ @@ -1739,6 +1740,13 @@ mod redundant_pattern_match { /// deallocate memory. For these types, and composites containing them, changing the drop order /// won't result in any observable side effects. fn type_needs_ordered_drop(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + type_needs_ordered_drop_inner(cx, ty, &mut FxHashSet::default()) + } + + fn type_needs_ordered_drop_inner(cx: &LateContext<'tcx>, ty: Ty<'tcx>, seen: &mut FxHashSet>) -> bool { + if !seen.insert(ty) { + return false; + } if !ty.needs_drop(cx.tcx, cx.param_env) { false } else if !cx @@ -1750,12 +1758,12 @@ mod redundant_pattern_match { // This type doesn't implement drop, so no side effects here. // Check if any component type has any. match ty.kind() { - ty::Tuple(_) => ty.tuple_fields().any(|ty| type_needs_ordered_drop(cx, ty)), - ty::Array(ty, _) => type_needs_ordered_drop(cx, ty), + ty::Tuple(_) => ty.tuple_fields().any(|ty| type_needs_ordered_drop_inner(cx, ty, seen)), + ty::Array(ty, _) => type_needs_ordered_drop_inner(cx, ty, seen), ty::Adt(adt, subs) => adt .all_fields() .map(|f| f.ty(cx.tcx, subs)) - .any(|ty| type_needs_ordered_drop(cx, ty)), + .any(|ty| type_needs_ordered_drop_inner(cx, ty, seen)), _ => true, } } @@ -1772,7 +1780,7 @@ mod redundant_pattern_match { { // Check all of the generic arguments. if let ty::Adt(_, subs) = ty.kind() { - subs.types().any(|ty| type_needs_ordered_drop(cx, ty)) + subs.types().any(|ty| type_needs_ordered_drop_inner(cx, ty, seen)) } else { true } diff --git a/tests/ui/crashes/ice-7169.rs b/tests/ui/crashes/ice-7169.rs new file mode 100644 index 00000000000..82095febc19 --- /dev/null +++ b/tests/ui/crashes/ice-7169.rs @@ -0,0 +1,9 @@ +#[derive(Default)] +struct A { + a: Vec>, + b: T, +} + +fn main() { + if let Ok(_) = Ok::<_, ()>(A::::default()) {} +} diff --git a/tests/ui/crashes/ice-7169.stderr b/tests/ui/crashes/ice-7169.stderr new file mode 100644 index 00000000000..5a9cd32380a --- /dev/null +++ b/tests/ui/crashes/ice-7169.stderr @@ -0,0 +1,10 @@ +error: redundant pattern matching, consider using `is_ok()` + --> $DIR/ice-7169.rs:8:12 + | +LL | if let Ok(_) = Ok::<_, ()>(A::::default()) {} + | -------^^^^^-------------------------------------- help: try this: `if Ok::<_, ()>(A::::default()).is_ok()` + | + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` + +error: aborting due to previous error +