about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-05 17:33:46 +0000
committerflip1995 <philipp.krones@embecosm.com>2021-05-10 10:21:25 +0200
commit98b11c8f7bfd7efd5044b6011ba1f4d71f46b223 (patch)
treeab33b4af969ed50a3af041889044b6bf9acb631b
parent7c7683c8efe447b251d6c5ca6cce51233060f6e8 (diff)
downloadrust-98b11c8f7bfd7efd5044b6011ba1f4d71f46b223.tar.gz
rust-98b11c8f7bfd7efd5044b6011ba1f4d71f46b223.zip
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)
-rw-r--r--clippy_lints/src/matches.rs16
-rw-r--r--tests/ui/crashes/ice-7169.rs9
-rw-r--r--tests/ui/crashes/ice-7169.stderr10
3 files changed, 31 insertions, 4 deletions
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<Ty<'tcx>>) -> 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<T> {
+    a: Vec<A<T>>,
+    b: T,
+}
+
+fn main() {
+    if let Ok(_) = Ok::<_, ()>(A::<String>::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::<String>::default()) {}
+   |     -------^^^^^-------------------------------------- help: try this: `if Ok::<_, ()>(A::<String>::default()).is_ok()`
+   |
+   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+
+error: aborting due to previous error
+