Skip to content

Commit 59794f7

Browse files
committed
Fix lint.
1 parent 276f399 commit 59794f7

File tree

4 files changed

+35
-197
lines changed

4 files changed

+35
-197
lines changed

compiler/rustc_lint/src/types.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,14 @@ pub fn transparent_newtype_field<'a, 'tcx>(
984984
}
985985

986986
/// Is type known to be non-null?
987-
fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, mode: CItemKind) -> bool {
987+
fn ty_is_known_nonnull<'tcx>(
988+
tcx: TyCtxt<'tcx>,
989+
param_env: ty::ParamEnv<'tcx>,
990+
ty: Ty<'tcx>,
991+
mode: CItemKind,
992+
) -> bool {
993+
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
994+
988995
match ty.kind() {
989996
ty::FnPtr(_) => true,
990997
ty::Ref(..) => true,
@@ -1004,15 +1011,21 @@ fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, mode: CItemKind) -
10041011
def.variants()
10051012
.iter()
10061013
.filter_map(|variant| transparent_newtype_field(tcx, variant))
1007-
.any(|field| ty_is_known_nonnull(tcx, field.ty(tcx, args), mode))
1014+
.any(|field| ty_is_known_nonnull(tcx, param_env, field.ty(tcx, args), mode))
10081015
}
10091016
_ => false,
10101017
}
10111018
}
10121019

10131020
/// Given a non-null scalar (or transparent) type `ty`, return the nullable version of that type.
10141021
/// If the type passed in was not scalar, returns None.
1015-
fn get_nullable_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
1022+
fn get_nullable_type<'tcx>(
1023+
tcx: TyCtxt<'tcx>,
1024+
param_env: ty::ParamEnv<'tcx>,
1025+
ty: Ty<'tcx>,
1026+
) -> Option<Ty<'tcx>> {
1027+
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
1028+
10161029
Some(match *ty.kind() {
10171030
ty::Adt(field_def, field_args) => {
10181031
let inner_field_ty = {
@@ -1028,22 +1041,19 @@ fn get_nullable_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>>
10281041
.expect("No non-zst fields in transparent type.")
10291042
.ty(tcx, field_args)
10301043
};
1031-
return get_nullable_type(tcx, inner_field_ty);
1044+
return get_nullable_type(tcx, param_env, inner_field_ty);
10321045
}
10331046
ty::Int(ty) => Ty::new_int(tcx, ty),
10341047
ty::Uint(ty) => Ty::new_uint(tcx, ty),
10351048
ty::RawPtr(ty_mut) => Ty::new_ptr(tcx, ty_mut),
10361049
// As these types are always non-null, the nullable equivalent of
1037-
// Option<T> of these types are their raw pointer counterparts.
1050+
// `Option<T>` of these types are their raw pointer counterparts.
10381051
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty::TypeAndMut { ty, mutbl }),
1039-
ty::FnPtr(..) => {
1040-
// There is no nullable equivalent for Rust's function pointers -- you
1041-
// must use an Option<fn(..) -> _> to represent it.
1042-
ty
1043-
}
1044-
1045-
// We should only ever reach this case if ty_is_known_nonnull is extended
1046-
// to other types.
1052+
// There is no nullable equivalent for Rust's function pointers,
1053+
// you must use an `Option<fn(..) -> _>` to represent it.
1054+
ty::FnPtr(..) => ty,
1055+
// We should only ever reach this case if `ty_is_known_nonnull` is
1056+
// extended to other types.
10471057
ref unhandled => {
10481058
debug!(
10491059
"get_nullable_type: Unhandled scalar kind: {:?} while checking {:?}",
@@ -1056,7 +1066,7 @@ fn get_nullable_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>>
10561066

10571067
/// Check if this enum can be safely exported based on the "nullable pointer optimization". If it
10581068
/// can, return the type that `ty` can be safely converted to, otherwise return `None`.
1059-
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`,
1069+
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero`,
10601070
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
10611071
/// FIXME: This duplicates code in codegen.
10621072
pub(crate) fn repr_nullable_ptr<'tcx>(
@@ -1075,7 +1085,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
10751085
_ => return None,
10761086
};
10771087

1078-
if !ty_is_known_nonnull(tcx, field_ty, ckind) {
1088+
if !ty_is_known_nonnull(tcx, param_env, field_ty, ckind) {
10791089
return None;
10801090
}
10811091

@@ -1099,10 +1109,10 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
10991109
WrappingRange { start: 0, end }
11001110
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
11011111
{
1102-
return Some(get_nullable_type(tcx, field_ty).unwrap());
1112+
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
11031113
}
11041114
WrappingRange { start: 1, .. } => {
1105-
return Some(get_nullable_type(tcx, field_ty).unwrap());
1115+
return Some(get_nullable_type(tcx, param_env, field_ty).unwrap());
11061116
}
11071117
WrappingRange { start, end } => {
11081118
unreachable!("Unhandled start and end range: ({}, {})", start, end)

library/core/src/num/nonzero.rs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl_zeroable_primitive!(
103103
/// ```
104104
#[unstable(feature = "generic_nonzero", issue = "120257")]
105105
#[repr(transparent)]
106+
#[rustc_nonnull_optimization_guaranteed]
106107
#[rustc_diagnostic_item = "NonZero"]
107108
pub struct NonZero<T: ZeroablePrimitive>(T::NonZeroInner);
108109

tests/ui/lint/clashing-extern-fn.stderr

+2-65
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,3 @@
1-
warning: `extern` block uses type `Option<NonZero<usize>>`, which is not FFI-safe
2-
--> $DIR/clashing-extern-fn.rs:369:43
3-
|
4-
LL | fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
6-
|
7-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
8-
= note: enum has no representation hint
9-
= note: `#[warn(improper_ctypes)]` on by default
10-
11-
warning: `extern` block uses type `Option<NonZero<isize>>`, which is not FFI-safe
12-
--> $DIR/clashing-extern-fn.rs:370:43
13-
|
14-
LL | fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
15-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
16-
|
17-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
18-
= note: enum has no representation hint
19-
20-
warning: `extern` block uses type `Option<Transparent>`, which is not FFI-safe
21-
--> $DIR/clashing-extern-fn.rs:428:46
22-
|
23-
LL | fn hidden_niche_transparent() -> Option<Transparent>;
24-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
25-
|
26-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
27-
= note: enum has no representation hint
28-
291
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
302
--> $DIR/clashing-extern-fn.rs:430:55
313
|
@@ -34,6 +6,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
346
|
357
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
368
= note: enum has no representation hint
9+
= note: `#[warn(improper_ctypes)]` on by default
3710

3811
warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
3912
--> $DIR/clashing-extern-fn.rs:434:46
@@ -205,30 +178,6 @@ LL | fn non_null_ptr() -> *const usize;
205178
= note: expected `unsafe extern "C" fn() -> NonNull<usize>`
206179
found `unsafe extern "C" fn() -> *const usize`
207180

208-
warning: `option_non_zero_usize` redeclared with a different signature
209-
--> $DIR/clashing-extern-fn.rs:369:13
210-
|
211-
LL | fn option_non_zero_usize() -> usize;
212-
| ----------------------------------- `option_non_zero_usize` previously declared here
213-
...
214-
LL | fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
215-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
216-
|
217-
= note: expected `unsafe extern "C" fn() -> usize`
218-
found `unsafe extern "C" fn() -> Option<NonZero<usize>>`
219-
220-
warning: `option_non_zero_isize` redeclared with a different signature
221-
--> $DIR/clashing-extern-fn.rs:370:13
222-
|
223-
LL | fn option_non_zero_isize() -> isize;
224-
| ----------------------------------- `option_non_zero_isize` previously declared here
225-
...
226-
LL | fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
227-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
228-
|
229-
= note: expected `unsafe extern "C" fn() -> isize`
230-
found `unsafe extern "C" fn() -> Option<NonZero<isize>>`
231-
232181
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
233182
--> $DIR/clashing-extern-fn.rs:374:13
234183
|
@@ -253,18 +202,6 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize;
253202
= note: expected `unsafe extern "C" fn() -> *const usize`
254203
found `unsafe extern "C" fn() -> *const isize`
255204

256-
warning: `hidden_niche_transparent` redeclared with a different signature
257-
--> $DIR/clashing-extern-fn.rs:428:13
258-
|
259-
LL | fn hidden_niche_transparent() -> usize;
260-
| -------------------------------------- `hidden_niche_transparent` previously declared here
261-
...
262-
LL | fn hidden_niche_transparent() -> Option<Transparent>;
263-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
264-
|
265-
= note: expected `unsafe extern "C" fn() -> usize`
266-
found `unsafe extern "C" fn() -> Option<Transparent>`
267-
268205
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
269206
--> $DIR/clashing-extern-fn.rs:430:13
270207
|
@@ -289,5 +226,5 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
289226
= note: expected `unsafe extern "C" fn() -> usize`
290227
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
291228

292-
warning: 25 warnings emitted
229+
warning: 19 warnings emitted
293230

tests/ui/lint/lint-ctypes-enum.stderr

+5-115
Original file line numberDiff line numberDiff line change
@@ -45,131 +45,21 @@ note: the type is defined here
4545
LL | enum T {
4646
| ^^^^^^
4747

48-
error: `extern` block uses type `Option<NonZero<u8>>`, which is not FFI-safe
49-
--> $DIR/lint-ctypes-enum.rs:71:21
50-
|
51-
LL | fn nonzero_u8(x: Option<num::NonZero<u8>>);
52-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
53-
|
54-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
55-
= note: enum has no representation hint
56-
57-
error: `extern` block uses type `Option<NonZero<u16>>`, which is not FFI-safe
58-
--> $DIR/lint-ctypes-enum.rs:72:22
59-
|
60-
LL | fn nonzero_u16(x: Option<num::NonZero<u16>>);
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
62-
|
63-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
64-
= note: enum has no representation hint
65-
66-
error: `extern` block uses type `Option<NonZero<u32>>`, which is not FFI-safe
67-
--> $DIR/lint-ctypes-enum.rs:73:22
68-
|
69-
LL | fn nonzero_u32(x: Option<num::NonZero<u32>>);
70-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
71-
|
72-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
73-
= note: enum has no representation hint
74-
75-
error: `extern` block uses type `Option<NonZero<u64>>`, which is not FFI-safe
76-
--> $DIR/lint-ctypes-enum.rs:74:22
77-
|
78-
LL | fn nonzero_u64(x: Option<num::NonZero<u64>>);
79-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
80-
|
81-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
82-
= note: enum has no representation hint
83-
84-
error: `extern` block uses type `Option<NonZero<u128>>`, which is not FFI-safe
48+
error: `extern` block uses type `u128`, which is not FFI-safe
8549
--> $DIR/lint-ctypes-enum.rs:75:23
8650
|
8751
LL | fn nonzero_u128(x: Option<num::NonZero<u128>>);
8852
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
8953
|
90-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
91-
= note: enum has no representation hint
92-
93-
error: `extern` block uses type `Option<NonZero<usize>>`, which is not FFI-safe
94-
--> $DIR/lint-ctypes-enum.rs:77:24
95-
|
96-
LL | fn nonzero_usize(x: Option<num::NonZero<usize>>);
97-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
98-
|
99-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
100-
= note: enum has no representation hint
101-
102-
error: `extern` block uses type `Option<NonZero<i8>>`, which is not FFI-safe
103-
--> $DIR/lint-ctypes-enum.rs:78:21
104-
|
105-
LL | fn nonzero_i8(x: Option<num::NonZero<i8>>);
106-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
107-
|
108-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
109-
= note: enum has no representation hint
110-
111-
error: `extern` block uses type `Option<NonZero<i16>>`, which is not FFI-safe
112-
--> $DIR/lint-ctypes-enum.rs:79:22
113-
|
114-
LL | fn nonzero_i16(x: Option<num::NonZero<i16>>);
115-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
116-
|
117-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
118-
= note: enum has no representation hint
119-
120-
error: `extern` block uses type `Option<NonZero<i32>>`, which is not FFI-safe
121-
--> $DIR/lint-ctypes-enum.rs:80:22
122-
|
123-
LL | fn nonzero_i32(x: Option<num::NonZero<i32>>);
124-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
125-
|
126-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
127-
= note: enum has no representation hint
128-
129-
error: `extern` block uses type `Option<NonZero<i64>>`, which is not FFI-safe
130-
--> $DIR/lint-ctypes-enum.rs:81:22
131-
|
132-
LL | fn nonzero_i64(x: Option<num::NonZero<i64>>);
133-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
134-
|
135-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
136-
= note: enum has no representation hint
54+
= note: 128-bit integers don't currently have a known stable ABI
13755

138-
error: `extern` block uses type `Option<NonZero<i128>>`, which is not FFI-safe
56+
error: `extern` block uses type `i128`, which is not FFI-safe
13957
--> $DIR/lint-ctypes-enum.rs:82:23
14058
|
14159
LL | fn nonzero_i128(x: Option<num::NonZero<i128>>);
14260
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
14361
|
144-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
145-
= note: enum has no representation hint
146-
147-
error: `extern` block uses type `Option<NonZero<isize>>`, which is not FFI-safe
148-
--> $DIR/lint-ctypes-enum.rs:84:24
149-
|
150-
LL | fn nonzero_isize(x: Option<num::NonZero<isize>>);
151-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
152-
|
153-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
154-
= note: enum has no representation hint
155-
156-
error: `extern` block uses type `Option<TransparentStruct<NonZero<u8>>>`, which is not FFI-safe
157-
--> $DIR/lint-ctypes-enum.rs:85:29
158-
|
159-
LL | fn transparent_struct(x: Option<TransparentStruct<num::NonZero<u8>>>);
160-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
161-
|
162-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
163-
= note: enum has no representation hint
164-
165-
error: `extern` block uses type `Option<TransparentEnum<NonZero<u8>>>`, which is not FFI-safe
166-
--> $DIR/lint-ctypes-enum.rs:86:27
167-
|
168-
LL | fn transparent_enum(x: Option<TransparentEnum<num::NonZero<u8>>>);
169-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
170-
|
171-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
172-
= note: enum has no representation hint
62+
= note: 128-bit integers don't currently have a known stable ABI
17363

17464
error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
17565
--> $DIR/lint-ctypes-enum.rs:87:28
@@ -198,5 +88,5 @@ LL | fn no_result(x: Result<(), num::NonZero<i32>>);
19888
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
19989
= note: enum has no representation hint
20090

201-
error: aborting due to 20 previous errors
91+
error: aborting due to 8 previous errors
20292

0 commit comments

Comments
 (0)