@@ -73,26 +73,24 @@ fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
73
73
}
74
74
75
75
fn struct_all_fields_are_public ( tcx : TyCtxt < ' _ > , id : LocalDefId ) -> bool {
76
- let adt_def = tcx. adt_def ( id) ;
77
-
78
- // skip types contain fields of unit and never type,
79
- // it's usually intentional to make the type not constructible
80
- let not_require_constructor = adt_def. all_fields ( ) . any ( |field| {
76
+ // treat PhantomData and positional ZST as public,
77
+ // we don't want to lint types which only have them,
78
+ // cause it's a common way to use such types to check things like well-formedness
79
+ tcx. adt_def ( id) . all_fields ( ) . all ( |field| {
81
80
let field_type = tcx. type_of ( field. did ) . instantiate_identity ( ) ;
82
- field_type. is_unit ( ) || field_type. is_never ( )
83
- } ) ;
84
-
85
- not_require_constructor
86
- || adt_def. all_fields ( ) . all ( |field| {
87
- let field_type = tcx. type_of ( field. did ) . instantiate_identity ( ) ;
88
- // skip fields of PhantomData,
89
- // cause it's a common way to check things like well-formedness
90
- if field_type. is_phantom_data ( ) {
91
- return true ;
92
- }
93
-
94
- field. vis . is_public ( )
95
- } )
81
+ if field_type. is_phantom_data ( ) {
82
+ return true ;
83
+ }
84
+ let is_positional = field. name . as_str ( ) . starts_with ( |c : char | c. is_ascii_digit ( ) ) ;
85
+ if is_positional
86
+ && tcx
87
+ . layout_of ( tcx. param_env ( field. did ) . and ( field_type) )
88
+ . map_or ( true , |layout| layout. is_zst ( ) )
89
+ {
90
+ return true ;
91
+ }
92
+ field. vis . is_public ( )
93
+ } )
96
94
}
97
95
98
96
/// check struct and its fields are public or not,
0 commit comments