|
1 | 1 | use clippy_utils::diagnostics::span_lint_and_sugg;
|
2 |
| -use rustc_lint::{EarlyContext, EarlyLintPass}; |
3 |
| -use rustc_lint_defs::Applicability; |
| 2 | +// use clippy_utils::is_integer_const; |
| 3 | +use clippy_utils::consts::{miri_to_const, Constant}; |
| 4 | +use rustc_errors::Applicability; |
| 5 | +use rustc_hir::{Item, ItemKind, TyKind, VariantData}; |
| 6 | +use rustc_lint::{LateContext, LateLintPass}; |
4 | 7 | use rustc_session::{declare_lint_pass, declare_tool_lint};
|
5 | 8 |
|
6 | 9 | declare_clippy_lint! {
|
@@ -36,38 +39,55 @@ declare_lint_pass!(TrailingZeroSizedArrayWithoutReprC => [TRAILING_ZERO_SIZED_AR
|
36 | 39 | // TODO: Register the lint pass in `clippy_lints/src/lib.rs`,
|
37 | 40 | // e.g. store.register_early_pass(||
|
38 | 41 | // Box::new(trailing_zero_sized_array_without_repr_c::TrailingZeroSizedArrayWithoutReprC));
|
| 42 | +// DONE! |
39 | 43 |
|
40 |
| -impl EarlyLintPass for TrailingZeroSizedArrayWithoutReprC { |
41 |
| - fn check_struct_def(&mut self, cx: &EarlyContext<'_>, data: &rustc_ast::VariantData) { |
42 |
| - if is_struct_with_trailing_zero_sized_array(cx, data) && !has_repr_c(cx, data) { |
43 |
| - span_lint_and_sugg( |
44 |
| - cx, |
45 |
| - todo!(), |
46 |
| - todo!(), |
47 |
| - todo!(), |
48 |
| - "try", |
49 |
| - "`#[repr(C)]`".to_string(), |
50 |
| - Applicability::MachineApplicable, |
51 |
| - ) |
| 44 | +impl<'tcx> LateLintPass<'tcx> for TrailingZeroSizedArrayWithoutReprC { |
| 45 | + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { |
| 46 | + if is_struct_with_trailing_zero_sized_array(cx, item) |
| 47 | + /* && !has_repr_c(cx, item) */ |
| 48 | + { |
| 49 | + // span_lint_and_sugg( |
| 50 | + // cx, |
| 51 | + // todo!(), |
| 52 | + // todo!(), |
| 53 | + // todo!(), |
| 54 | + // "try", |
| 55 | + // "`#[repr(C)]`".to_string(), |
| 56 | + // Applicability::MachineApplicable, |
| 57 | + // ); |
| 58 | + // println!("consider yourself linted 😎"); |
52 | 59 | }
|
53 | 60 | }
|
54 | 61 | }
|
55 | 62 |
|
56 |
| -fn is_struct_with_trailing_zero_sized_array(cx: &EarlyContext<'_>, data: &rustc_ast::VariantData) -> bool { |
| 63 | +fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool { |
| 64 | + dbg!(item.ident); |
57 | 65 | if_chain! {
|
58 |
| - if let rustc_ast::ast::VariantData::Struct(field_defs, some_bool_huh) = data; |
| 66 | + if let ItemKind::Struct(data, _generics) = &item.kind; |
| 67 | + if let VariantData::Struct(field_defs, _) = data; |
59 | 68 | if let Some(last_field) = field_defs.last();
|
60 |
| - if let rustc_ast::ast::TyKind::Array(_, aconst) = &last_field.ty.kind; |
61 |
| - // TODO: if array is zero-sized; |
| 69 | + if let TyKind::Array(_, aconst) = last_field.ty.kind; |
| 70 | + let aconst_def_id = cx.tcx.hir().body_owner_def_id(aconst.body).to_def_id(); |
| 71 | + let ty = cx.tcx.type_of(aconst_def_id); |
| 72 | + let constant = cx |
| 73 | + .tcx |
| 74 | + .const_eval_poly(aconst_def_id) // NOTE: maybe const_eval_resolve? seems especially cursed to be using a const expr which resolves to 0 to create a zero-sized array, tho |
| 75 | + .ok() |
| 76 | + .map(|val| rustc_middle::ty::Const::from_value(cx.tcx, val, ty)); |
| 77 | + if let Some(Constant::Int(val)) = constant.and_then(miri_to_const); |
| 78 | + if val == 0; |
62 | 79 | then {
|
63 |
| - dbg!(aconst); |
| 80 | + eprintln!("true"); |
64 | 81 | true
|
65 | 82 | } else {
|
| 83 | + // dbg!(aconst); |
| 84 | + eprintln!("false"); |
66 | 85 | false
|
67 | 86 | }
|
68 | 87 | }
|
69 | 88 | }
|
70 | 89 |
|
71 |
| -fn has_repr_c(cx: &EarlyContext<'_>, data: &rustc_ast::VariantData) -> bool { |
72 |
| - todo!() |
| 90 | +fn has_repr_c(cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) -> bool { |
| 91 | + // todo!() |
| 92 | + true |
73 | 93 | }
|
0 commit comments