Skip to content

Commit c734436

Browse files
committed
lint ImproperCTypes: misc. changes due to review
- relaxed the uninhabited types allowed on function return
1 parent cecee60 commit c734436

File tree

4 files changed

+20
-91
lines changed

4 files changed

+20
-91
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,10 +436,7 @@ lint_improper_ctypes_tuple_help = consider using a struct instead
436436
lint_improper_ctypes_tuple_reason = tuples have unspecified layout
437437
438438
lint_improper_ctypes_uninhabited_enum = zero-variant enums and other uninhabited types are not allowed in function arguments and static variables
439-
lint_improper_ctypes_uninhabited_enum_deep = zero-variant enums and other uninhabited types are only allowed in function returns if used directly
440439
lint_improper_ctypes_uninhabited_never = the never type (`!`) and other uninhabited types are not allowed in function arguments and static variables
441-
lint_improper_ctypes_uninhabited_never_deep = the never type (`!`) and other uninhabited types are only allowed in function returns if used directly
442-
lint_improper_ctypes_uninhabited_use_direct = if you meant to have a function that never returns, consider setting its return type to the never type (`!`) or a zero-variant enum
443440
444441
lint_improper_ctypes_union_consider_transparent = `{$ty}` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
445442
lint_improper_ctypes_union_fieldless_help = consider adding a member to this union

compiler/rustc_lint/src/types/improper_ctypes.rs

Lines changed: 15 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -585,37 +585,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
585585
fn visit_uninhabited(
586586
&self,
587587
state: CTypesVisitorState,
588-
outer_ty: Option<Ty<'tcx>>,
589588
ty: Ty<'tcx>,
590589
) -> FfiResult<'tcx> {
591-
if state.is_in_function_return()
592-
&& matches!(outer_ty.map(|ty| ty.kind()), None | Some(ty::FnPtr(..)))
593-
{
590+
if state.is_in_function_return() {
594591
FfiResult::FfiSafe
595592
} else {
596-
let help = if state.is_in_function_return() {
597-
Some(fluent::lint_improper_ctypes_uninhabited_use_direct)
598-
} else {
599-
None
600-
};
601593
let desc = match ty.kind() {
602-
ty::Adt(..) => {
603-
if state.is_in_function_return() {
604-
fluent::lint_improper_ctypes_uninhabited_enum_deep
605-
} else {
606-
fluent::lint_improper_ctypes_uninhabited_enum
607-
}
608-
}
609-
ty::Never => {
610-
if state.is_in_function_return() {
611-
fluent::lint_improper_ctypes_uninhabited_never_deep
612-
} else {
613-
fluent::lint_improper_ctypes_uninhabited_never
614-
}
615-
}
594+
ty::Adt(..) => fluent::lint_improper_ctypes_uninhabited_enum,
595+
ty::Never => fluent::lint_improper_ctypes_uninhabited_never,
616596
r @ _ => bug!("unexpected ty_kind in uninhabited type handling: {:?}", r),
617597
};
618-
FfiResult::new_with_reason(ty, desc, help)
598+
FfiResult::new_with_reason(ty, desc, None)
619599
}
620600
}
621601

@@ -771,7 +751,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
771751
// determine if there is 0 or 1 non-1ZST field, and which it is.
772752
// (note: for enums, "transparent" means 1-variant)
773753
if ty.is_privately_uninhabited(self.cx.tcx, self.cx.typing_env()) {
774-
// let's consider transparent structs are considered unsafe if uninhabited,
754+
// let's consider transparent structs to be maybe unsafe if uninhabited,
775755
// even if that is because of fields otherwise ignored in FFI-safety checks
776756
// FIXME: and also maybe this should be "!is_inhabited_from" but from where?
777757
ffires_accumulator += variant
@@ -782,9 +762,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
782762
let mut field_res = self.visit_type(state, Some(ty), field_ty);
783763
field_res.take_with_core_note(&[
784764
fluent::lint_improper_ctypes_uninhabited_enum,
785-
fluent::lint_improper_ctypes_uninhabited_enum_deep,
786765
fluent::lint_improper_ctypes_uninhabited_never,
787-
fluent::lint_improper_ctypes_uninhabited_never_deep,
788766
])
789767
})
790768
.reduce(|r1, r2| r1 + r2)
@@ -876,19 +854,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
876854
let help = if non_1zst_count == 1
877855
&& last_non_1zst.map(|field_i| fields_ok_list[field_i]) == Some(true)
878856
{
879-
if ty.is_privately_uninhabited(self.cx.tcx, self.cx.typing_env()) {
880-
// uninhabited types can't be helped by being turned transparent
881-
None
882-
} else {
883-
match def.adt_kind() {
884-
AdtKind::Struct => {
885-
Some(fluent::lint_improper_ctypes_struct_consider_transparent)
886-
}
887-
AdtKind::Union => {
888-
Some(fluent::lint_improper_ctypes_union_consider_transparent)
889-
}
890-
AdtKind::Enum => bug!("cannot suggest an enum to be repr(transparent)"),
857+
match def.adt_kind() {
858+
AdtKind::Struct => {
859+
Some(fluent::lint_improper_ctypes_struct_consider_transparent)
891860
}
861+
AdtKind::Union => {
862+
Some(fluent::lint_improper_ctypes_union_consider_transparent)
863+
}
864+
AdtKind::Enum => bug!("cannot suggest an enum to be repr(transparent)"),
892865
}
893866
} else {
894867
None
@@ -982,7 +955,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
982955
fn visit_enum(
983956
&self,
984957
state: CTypesVisitorState,
985-
outer_ty: Option<Ty<'tcx>>,
986958
ty: Ty<'tcx>,
987959
def: AdtDef<'tcx>,
988960
args: GenericArgsRef<'tcx>,
@@ -992,7 +964,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
992964

993965
if def.variants().is_empty() {
994966
// Empty enums are implicitely handled as the never type:
995-
return self.visit_uninhabited(state, outer_ty, ty);
967+
return self.visit_uninhabited(state, ty);
996968
}
997969
// Check for a repr() attribute to specify the size of the
998970
// discriminant.
@@ -1050,9 +1022,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10501022
let mut variant_res = self.visit_variant_fields(state, ty, def, variant, args);
10511023
variants_uninhabited_ffires[variant_i] = variant_res.take_with_core_note(&[
10521024
fluent::lint_improper_ctypes_uninhabited_enum,
1053-
fluent::lint_improper_ctypes_uninhabited_enum_deep,
10541025
fluent::lint_improper_ctypes_uninhabited_never,
1055-
fluent::lint_improper_ctypes_uninhabited_never_deep,
10561026
]);
10571027
// FIXME: check that enums allow any (up to all) variants to be phantoms?
10581028
// (previous code says no, but I don't know why? the problem with phantoms is that they're ZSTs, right?)
@@ -1110,7 +1080,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11101080
}
11111081
self.visit_struct_or_union(state, ty, def, args)
11121082
}
1113-
AdtKind::Enum => self.visit_enum(state, outer_ty, ty, def, args),
1083+
AdtKind::Enum => self.visit_enum(state, ty, def, args),
11141084
}
11151085
}
11161086

@@ -1245,7 +1215,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12451215

12461216
ty::Foreign(..) => FfiSafe,
12471217

1248-
ty::Never => self.visit_uninhabited(state, outer_ty, ty),
1218+
ty::Never => self.visit_uninhabited(state, ty),
12491219

12501220
// This is only half of the checking-for-opaque-aliases story:
12511221
// since they are liable to vanish on normalisation, we need a specific to find them through

tests/ui/lint/improper_ctypes/lint_uninhabited.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct HalfHiddenUninhabited {
3232
extern "C" {
3333

3434
fn bad_entry(e: AlsoUninhabited); //~ ERROR: uses type `AlsoUninhabited`
35-
fn bad_exit()->AlsoUninhabited; //~ ERROR: uses type `AlsoUninhabited`
35+
fn bad_exit()->AlsoUninhabited;
3636

3737
fn bad0_entry(e: Uninhabited); //~ ERROR: uses type `Uninhabited`
3838
fn bad0_exit()->Uninhabited;
@@ -46,7 +46,7 @@ fn never_exit()->!;
4646
}
4747

4848
extern "C" fn impl_bad_entry(e: AlsoUninhabited) {} //~ ERROR: uses type `AlsoUninhabited`
49-
extern "C" fn impl_bad_exit()->AlsoUninhabited { //~ ERROR: uses type `AlsoUninhabited`
49+
extern "C" fn impl_bad_exit()->AlsoUninhabited {
5050
AlsoUninhabited{
5151
a: impl_bad0_exit(),
5252
b: 0,

tests/ui/lint/improper_ctypes/lint_uninhabited.stderr

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ error: `extern` block uses type `AlsoUninhabited`, which is not FFI-safe
44
LL | fn bad_entry(e: AlsoUninhabited);
55
| ^^^^^^^^^^^^^^^ not FFI-safe
66
|
7+
= help: `AlsoUninhabited` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
78
= note: this struct/enum/union (`AlsoUninhabited`) is FFI-unsafe due to a `Uninhabited` field
89
note: the type is defined here
910
--> $DIR/lint_uninhabited.rs:12:1
@@ -22,26 +23,6 @@ note: the lint level is defined here
2223
LL | #![deny(improper_ctypes)]
2324
| ^^^^^^^^^^^^^^^
2425

25-
error: `extern` block uses type `AlsoUninhabited`, which is not FFI-safe
26-
--> $DIR/lint_uninhabited.rs:35:16
27-
|
28-
LL | fn bad_exit()->AlsoUninhabited;
29-
| ^^^^^^^^^^^^^^^ not FFI-safe
30-
|
31-
= note: this struct/enum/union (`AlsoUninhabited`) is FFI-unsafe due to a `Uninhabited` field
32-
note: the type is defined here
33-
--> $DIR/lint_uninhabited.rs:12:1
34-
|
35-
LL | struct AlsoUninhabited{
36-
| ^^^^^^^^^^^^^^^^^^^^^^
37-
= help: if you meant to have a function that never returns, consider setting its return type to the never type (`!`) or a zero-variant enum
38-
= note: zero-variant enums and other uninhabited types are only allowed in function returns if used directly
39-
note: the type is defined here
40-
--> $DIR/lint_uninhabited.rs:9:1
41-
|
42-
LL | enum Uninhabited{}
43-
| ^^^^^^^^^^^^^^^^
44-
4526
error: `extern` block uses type `Uninhabited`, which is not FFI-safe
4627
--> $DIR/lint_uninhabited.rs:37:18
4728
|
@@ -69,6 +50,7 @@ error: `extern` fn uses type `AlsoUninhabited`, which is not FFI-safe
6950
LL | extern "C" fn impl_bad_entry(e: AlsoUninhabited) {}
7051
| ^^^^^^^^^^^^^^^ not FFI-safe
7152
|
53+
= help: `AlsoUninhabited` has exactly one non-zero-sized field, consider making it `#[repr(transparent)]` instead
7254
= note: this struct/enum/union (`AlsoUninhabited`) is FFI-unsafe due to a `Uninhabited` field
7355
note: the type is defined here
7456
--> $DIR/lint_uninhabited.rs:12:1
@@ -87,26 +69,6 @@ note: the lint level is defined here
8769
LL | #![deny(improper_c_fn_definitions, improper_c_callbacks)]
8870
| ^^^^^^^^^^^^^^^^^^^^^^^^^
8971

90-
error: `extern` fn uses type `AlsoUninhabited`, which is not FFI-safe
91-
--> $DIR/lint_uninhabited.rs:49:32
92-
|
93-
LL | extern "C" fn impl_bad_exit()->AlsoUninhabited {
94-
| ^^^^^^^^^^^^^^^ not FFI-safe
95-
|
96-
= note: this struct/enum/union (`AlsoUninhabited`) is FFI-unsafe due to a `Uninhabited` field
97-
note: the type is defined here
98-
--> $DIR/lint_uninhabited.rs:12:1
99-
|
100-
LL | struct AlsoUninhabited{
101-
| ^^^^^^^^^^^^^^^^^^^^^^
102-
= help: if you meant to have a function that never returns, consider setting its return type to the never type (`!`) or a zero-variant enum
103-
= note: zero-variant enums and other uninhabited types are only allowed in function returns if used directly
104-
note: the type is defined here
105-
--> $DIR/lint_uninhabited.rs:9:1
106-
|
107-
LL | enum Uninhabited{}
108-
| ^^^^^^^^^^^^^^^^
109-
11072
error: `extern` fn uses type `Uninhabited`, which is not FFI-safe
11173
--> $DIR/lint_uninhabited.rs:56:34
11274
|
@@ -155,5 +117,5 @@ LL | struct HalfHiddenUninhabited {
155117
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
156118
= note: the never type (`!`) and other uninhabited types are not allowed in function arguments and static variables
157119

158-
error: aborting due to 9 previous errors; 1 warning emitted
120+
error: aborting due to 7 previous errors; 1 warning emitted
159121

0 commit comments

Comments
 (0)