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