@@ -73,24 +73,26 @@ 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
- // 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| {
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| {
80
81
let field_type = tcx. type_of ( field. did ) . instantiate_identity ( ) ;
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
- } )
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
+ } )
94
96
}
95
97
96
98
/// check struct and its fields are public or not,
0 commit comments