about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrea Nall <anall@andreanall.com>2021-03-08 23:03:45 -0600
committerAndrea Nall <anall@andreanall.com>2021-03-08 23:03:45 -0600
commite322c773e3db22aadd60ce9a1803076fcbfeef2d (patch)
treed5219c4af1f7e17a58a2ee234b8a81f5592452db
parentb27cbda32b67b4fdd9113ed894b810fc8f3e180d (diff)
downloadrust-e322c773e3db22aadd60ce9a1803076fcbfeef2d.tar.gz
rust-e322c773e3db22aadd60ce9a1803076fcbfeef2d.zip
use TyS::walk
-rw-r--r--clippy_utils/src/lib.rs19
-rw-r--r--tests/ui/crashes/ice-6840.rs10
2 files changed, 17 insertions, 12 deletions
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 999b39852cd..ac29a09ae0e 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1504,9 +1504,7 @@ fn is_normalizable_helper<'tcx>(
     cache.insert(ty, false); // prevent recursive loops
     let result = cx.tcx.infer_ctxt().enter(|infcx| {
         let cause = rustc_middle::traits::ObligationCause::dummy();
-        if infcx.at(&cause, param_env).normalize(ty).is_err() {
-            false
-        } else {
+        if infcx.at(&cause, param_env).normalize(ty).is_ok() {
             match ty.kind() {
                 ty::Adt(def, substs) => !def.variants.iter().any(|variant| {
                     variant
@@ -1514,16 +1512,15 @@ fn is_normalizable_helper<'tcx>(
                         .iter()
                         .any(|field| !is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache))
                 }),
-                ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                    is_normalizable_helper(cx, param_env, pointee, cache)
-                },
-                ty::Array(inner_ty, _) | ty::Slice(inner_ty) => is_normalizable_helper(cx, param_env, inner_ty, cache),
-                ty::Tuple(tys) => !tys.iter().any(|inner| match inner.unpack() {
-                    GenericArgKind::Type(inner_ty) => !is_normalizable_helper(cx, param_env, inner_ty, cache),
-                    _ => false,
+                _ => !ty.walk().any(|generic_arg| !match generic_arg.unpack() {
+                    GenericArgKind::Type(inner_ty) if inner_ty != ty => {
+                        is_normalizable_helper(cx, param_env, inner_ty, cache)
+                    },
+                    _ => true, // if inner_ty == ty, we've already checked it
                 }),
-                _ => true,
             }
+        } else {
+            false
         }
     });
     cache.insert(ty, result);
diff --git a/tests/ui/crashes/ice-6840.rs b/tests/ui/crashes/ice-6840.rs
index a749eefb635..d789f60c5d5 100644
--- a/tests/ui/crashes/ice-6840.rs
+++ b/tests/ui/crashes/ice-6840.rs
@@ -13,11 +13,19 @@ pub struct RuleEdges<R: Rule> {
 
 type RuleDependencyEdges<R> = HashMap<u32, RuleEdges<R>>;
 
-// and additional potential variants
+// reproducer from the GitHub issue ends here
+//   but check some additional variants
 type RuleDependencyEdgesArray<R> = HashMap<u32, [RuleEdges<R>; 8]>;
 type RuleDependencyEdgesSlice<R> = HashMap<u32, &'static [RuleEdges<R>]>;
 type RuleDependencyEdgesRef<R> = HashMap<u32, &'static RuleEdges<R>>;
 type RuleDependencyEdgesRaw<R> = HashMap<u32, *const RuleEdges<R>>;
 type RuleDependencyEdgesTuple<R> = HashMap<u32, (RuleEdges<R>, RuleEdges<R>)>;
 
+// and an additional checks to make sure fix doesn't have stack-overflow issue
+//   on self-containing types
+pub struct SelfContaining {
+    inner: Box<SelfContaining>,
+}
+type SelfContainingEdges = HashMap<u32, SelfContaining>;
+
 fn main() {}