@@ -581,40 +581,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
581
581
}
582
582
583
583
/// Checks whether an uninhabited type (one without valid values) is safe-ish to have here
584
- fn visit_uninhabited (
585
- & self ,
586
- state : CTypesVisitorState ,
587
- outer_ty : Option < Ty < ' tcx > > ,
588
- ty : Ty < ' tcx > ,
589
- ) -> FfiResult < ' tcx > {
590
- if state. is_in_function_return ( )
591
- && matches ! ( outer_ty. map( |ty| ty. kind( ) ) , None | Some ( ty:: FnPtr ( ..) ) )
592
- {
584
+ fn visit_uninhabited ( & self , state : CTypesVisitorState , ty : Ty < ' tcx > ) -> FfiResult < ' tcx > {
585
+ if state. is_in_function_return ( ) {
593
586
FfiResult :: FfiSafe
594
587
} else {
595
- let help = if state. is_in_function_return ( ) {
596
- Some ( fluent:: lint_improper_ctypes_uninhabited_use_direct)
597
- } else {
598
- None
599
- } ;
600
588
let desc = match ty. kind ( ) {
601
- ty:: Adt ( ..) => {
602
- if state. is_in_function_return ( ) {
603
- fluent:: lint_improper_ctypes_uninhabited_enum_deep
604
- } else {
605
- fluent:: lint_improper_ctypes_uninhabited_enum
606
- }
607
- }
608
- ty:: Never => {
609
- if state. is_in_function_return ( ) {
610
- fluent:: lint_improper_ctypes_uninhabited_never_deep
611
- } else {
612
- fluent:: lint_improper_ctypes_uninhabited_never
613
- }
614
- }
589
+ ty:: Adt ( ..) => fluent:: lint_improper_ctypes_uninhabited_enum,
590
+ ty:: Never => fluent:: lint_improper_ctypes_uninhabited_never,
615
591
r @ _ => bug ! ( "unexpected ty_kind in uninhabited type handling: {:?}" , r) ,
616
592
} ;
617
- FfiResult :: new_with_reason ( ty, desc, help )
593
+ FfiResult :: new_with_reason ( ty, desc, None )
618
594
}
619
595
}
620
596
@@ -623,14 +599,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
623
599
fn visit_numeric ( & self , ty : Ty < ' tcx > ) -> FfiResult < ' tcx > {
624
600
// FIXME: for now, this is very incomplete, and seems to assume a x86_64 target
625
601
match ty. kind ( ) {
602
+ // note: before rust 1.77, 128-bit ints were not FFI-safe on x86_64
603
+ // ...they probably are still unsafe on i686 and other x86_32 architectures
626
604
ty:: Int ( ..) | ty:: Uint ( ..) | ty:: Float ( ..) => FfiResult :: FfiSafe ,
627
605
628
606
ty:: Char => FfiResult :: new_with_reason (
629
607
ty,
630
608
fluent:: lint_improper_ctypes_char_reason,
631
609
Some ( fluent:: lint_improper_ctypes_char_help) ,
632
610
) ,
633
- _ => bug ! ( "visit_numeric is to be called with numeric (int, float) types" ) ,
611
+ _ => bug ! ( "visit_numeric is to be called with numeric (char, int, float) types" ) ,
634
612
}
635
613
}
636
614
@@ -767,7 +745,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
767
745
// determine if there is 0 or 1 non-1ZST field, and which it is.
768
746
// (note: for enums, "transparent" means 1-variant)
769
747
if ty. is_privately_uninhabited ( self . cx . tcx , self . cx . typing_env ( ) ) {
770
- // let's consider transparent structs are considered unsafe if uninhabited,
748
+ // let's consider transparent structs to be maybe unsafe if uninhabited,
771
749
// even if that is because of fields otherwise ignored in FFI-safety checks
772
750
// FIXME: and also maybe this should be "!is_inhabited_from" but from where?
773
751
ffires_accumulator += variant
@@ -778,9 +756,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
778
756
let mut field_res = self . visit_type ( state, Some ( ty) , field_ty) ;
779
757
field_res. take_with_core_note ( & [
780
758
fluent:: lint_improper_ctypes_uninhabited_enum,
781
- fluent:: lint_improper_ctypes_uninhabited_enum_deep,
782
759
fluent:: lint_improper_ctypes_uninhabited_never,
783
- fluent:: lint_improper_ctypes_uninhabited_never_deep,
784
760
] )
785
761
} )
786
762
. reduce ( |r1, r2| r1 + r2)
@@ -872,19 +848,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
872
848
let help = if non_1zst_count == 1
873
849
&& last_non_1zst. map ( |field_i| fields_ok_list[ field_i] ) == Some ( true )
874
850
{
875
- if ty. is_privately_uninhabited ( self . cx . tcx , self . cx . typing_env ( ) ) {
876
- // uninhabited types can't be helped by being turned transparent
877
- None
878
- } else {
879
- match def. adt_kind ( ) {
880
- AdtKind :: Struct => {
881
- Some ( fluent:: lint_improper_ctypes_struct_consider_transparent)
882
- }
883
- AdtKind :: Union => {
884
- Some ( fluent:: lint_improper_ctypes_union_consider_transparent)
885
- }
886
- AdtKind :: Enum => bug ! ( "cannot suggest an enum to be repr(transparent)" ) ,
851
+ match def. adt_kind ( ) {
852
+ AdtKind :: Struct => {
853
+ Some ( fluent:: lint_improper_ctypes_struct_consider_transparent)
854
+ }
855
+ AdtKind :: Union => {
856
+ Some ( fluent:: lint_improper_ctypes_union_consider_transparent)
887
857
}
858
+ AdtKind :: Enum => bug ! ( "cannot suggest an enum to be repr(transparent)" ) ,
888
859
}
889
860
} else {
890
861
None
@@ -978,7 +949,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
978
949
fn visit_enum (
979
950
& self ,
980
951
state : CTypesVisitorState ,
981
- outer_ty : Option < Ty < ' tcx > > ,
982
952
ty : Ty < ' tcx > ,
983
953
def : AdtDef < ' tcx > ,
984
954
args : GenericArgsRef < ' tcx > ,
@@ -988,7 +958,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
988
958
989
959
if def. variants ( ) . is_empty ( ) {
990
960
// Empty enums are implicitely handled as the never type:
991
- return self . visit_uninhabited ( state, outer_ty , ty) ;
961
+ return self . visit_uninhabited ( state, ty) ;
992
962
}
993
963
// Check for a repr() attribute to specify the size of the
994
964
// discriminant.
@@ -1008,6 +978,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1008
978
) ;
1009
979
}
1010
980
981
+ // FIXME: connect `def.repr().int` to visit_numeric
982
+ // (for now it's OK, `repr(char)` doesn't exist and visit_numeric doesn't warn on anything else)
983
+
1011
984
let non_exhaustive = def. variant_list_has_applicable_non_exhaustive ( ) ;
1012
985
// Check the contained variants.
1013
986
@@ -1042,9 +1015,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1042
1015
let mut variant_res = self . visit_variant_fields ( state, ty, def, variant, args) ;
1043
1016
variants_uninhabited_ffires[ variant_i] = variant_res. take_with_core_note ( & [
1044
1017
fluent:: lint_improper_ctypes_uninhabited_enum,
1045
- fluent:: lint_improper_ctypes_uninhabited_enum_deep,
1046
1018
fluent:: lint_improper_ctypes_uninhabited_never,
1047
- fluent:: lint_improper_ctypes_uninhabited_never_deep,
1048
1019
] ) ;
1049
1020
// FIXME: check that enums allow any (up to all) variants to be phantoms?
1050
1021
// (previous code says no, but I don't know why? the problem with phantoms is that they're ZSTs, right?)
@@ -1102,7 +1073,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1102
1073
}
1103
1074
self . visit_struct_or_union ( state, ty, def, args)
1104
1075
}
1105
- AdtKind :: Enum => self . visit_enum ( state, outer_ty , ty, def, args) ,
1076
+ AdtKind :: Enum => self . visit_enum ( state, ty, def, args) ,
1106
1077
}
1107
1078
}
1108
1079
@@ -1237,7 +1208,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1237
1208
1238
1209
ty:: Foreign ( ..) => FfiSafe ,
1239
1210
1240
- ty:: Never => self . visit_uninhabited ( state, outer_ty , ty) ,
1211
+ ty:: Never => self . visit_uninhabited ( state, ty) ,
1241
1212
1242
1213
// This is only half of the checking-for-opaque-aliases story:
1243
1214
// since they are liable to vanish on normalisation, we need a specific to find them through
0 commit comments