about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs55
-rw-r--r--tests/ui/trailing_zero_sized_array_without_repr_c.rs32
2 files changed, 63 insertions, 24 deletions
diff --git a/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs b/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs
index bc055307d5e..de2513244da 100644
--- a/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs
+++ b/clippy_lints/src/trailing_zero_sized_array_without_repr_c.rs
@@ -64,35 +64,42 @@ impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC {
 }
 
 fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool {
-    if_chain! {
-        // First check if last field is an array
-        if let ItemKind::Struct(data, _) = &item.kind;
-        if let VariantData::Struct(field_defs, _) = data;
-        if let Some(last_field) = field_defs.last();
-        if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind;
+    // First check if last field is an array
+    if let ItemKind::Struct(data, _) = &item.kind {
+        if let VariantData::Struct(field_defs, _) = data {
+            if let Some(last_field) = field_defs.last() {
+                if let rustc_hir::TyKind::Array(_, length) = last_field.ty.kind {
+                    // Then check if that that array zero-sized
 
-        // Then check if that that array zero-sized
+                    // This is pretty much copied from `enum_clike.rs` and I don't fully understand it, so let me know
+                    // if there's a better way. I tried `Const::from_anon_const` but it didn't fold in the values
+                    // on the `ZeroSizedWithConst` and `ZeroSizedWithConstFunction` tests.
 
-        // This is pretty much copied from `enum_clike.rs` and I don't fully understand it, so let me know
-        // if there's a better way. I tried `Const::from_anon_const` but it didn't fold in the values
-        // on the `ZeroSizedWithConst` and `ZeroSizedWithConstFunction` tests.
-
-        // This line in particular seems convoluted.
-        let length_did = cx.tcx.hir().body_owner_def_id(length.body).to_def_id();
-        let length_ty = cx.tcx.type_of(length_did);
-        let length = cx
-            .tcx
-            .const_eval_poly(length_did)
-            .ok()
-            .map(|val| Const::from_value(cx.tcx, val, length_ty))
-            .and_then(miri_to_const);
-        if let Some(Constant::Int(length)) = length;
-        if length == 0;
-        then {
-            true
+                    // This line in particular seems convoluted.
+                    let length_did = cx.tcx.hir().body_owner_def_id(length.body).to_def_id();
+                    let length_ty = cx.tcx.type_of(length_did);
+                    let length = cx
+                        .tcx
+                        .const_eval_poly(length_did)
+                        .ok()
+                        .map(|val| Const::from_value(cx.tcx, val, length_ty))
+                        .and_then(miri_to_const);
+                    if let Some(Constant::Int(length)) = length {
+                        length == 0
+                    } else {
+                        false
+                    }
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
         } else {
             false
         }
+    } else {
+        false
     }
 }
 
diff --git a/tests/ui/trailing_zero_sized_array_without_repr_c.rs b/tests/ui/trailing_zero_sized_array_without_repr_c.rs
index 77b2c29b275..c6ee36e9685 100644
--- a/tests/ui/trailing_zero_sized_array_without_repr_c.rs
+++ b/tests/ui/trailing_zero_sized_array_without_repr_c.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::trailing_zero_sized_array_without_repr_c)]
+#![feature(const_generics_defaults)]
 
 // Do lint:
 
@@ -45,6 +46,10 @@ struct ZeroSizedWithConstFunction {
     last: [usize; compute_zero()],
 }
 
+struct ZeroSizedArrayWrapper([usize; 0]);
+
+struct TupleStruct(i32, [usize; 0]);
+
 struct LotsOfFields {
     f1: u32,
     f2: u32,
@@ -140,4 +145,31 @@ enum DontLintAnonymousStructsFromDesuraging {
     C { x: u32, y: [u64; 0] },
 }
 
+#[repr(C)]
+struct TupleStructReprC(i32, [usize; 0]);
+
+type NamedTuple = (i32, [usize; 0]);
+
+#[rustfmt::skip] // [rustfmt#4995](https://github.com/rust-lang/rustfmt/issues/4995)
+struct ConstParamZeroDefault<const N: usize = 0> {
+    field: i32,
+    last: [usize; N],
+}
+
+struct ConstParamNoDefault<const N: usize> {
+    field: i32,
+    last: [usize; N],
+}
+
+#[rustfmt::skip] 
+struct ConstParamNonZeroDefault<const N: usize = 1> {
+    field: i32,
+    last: [usize; N],
+}
+
+type A = ConstParamZeroDefault;
+type B = ConstParamZeroDefault<0>;
+type C = ConstParamNoDefault<0>;
+type D = ConstParamNonZeroDefault<0>;
+
 fn main() {}