Skip to content

Commit 2f3f83a

Browse files
authoredFeb 12, 2025
Rollup merge of #136193 - oli-obk:pattern-type-ffi-checks, r=chenyukang
Implement pattern type ffi checks Previously we just rejected pattern types outright in FFI, but that was never meant to be a permanent situation. We'll need them supported to use them as the building block for `NonZero` and `NonNull` after all (both of which are FFI safe). best reviewed commit by commit.
2 parents 5ebacd1 + f1f996a commit 2f3f83a

File tree

8 files changed

+178
-88
lines changed

8 files changed

+178
-88
lines changed
 

‎compiler/rustc_lint/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,6 @@ lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
390390
391391
lint_improper_ctypes_opaque = opaque types have no C equivalent
392392
393-
lint_improper_ctypes_pat_help = consider using the base type instead
394-
395-
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
396393
lint_improper_ctypes_slice_help = consider using a raw pointer instead
397394
398395
lint_improper_ctypes_slice_reason = slices have no C equivalent

‎compiler/rustc_lint/src/foreign_modules.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,7 @@ fn structurally_same_type_impl<'tcx>(
241241
if let ty::Adt(def, args) = *ty.kind() {
242242
let is_transparent = def.repr().transparent();
243243
let is_non_null = types::nonnull_optimization_guaranteed(tcx, def);
244-
debug!(
245-
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
246-
ty, is_transparent, is_non_null
247-
);
244+
debug!(?ty, is_transparent, is_non_null);
248245
if is_transparent && !is_non_null {
249246
debug_assert_eq!(def.variants().len(), 1);
250247
let v = &def.variant(FIRST_VARIANT);
@@ -378,14 +375,14 @@ fn structurally_same_type_impl<'tcx>(
378375

379376
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
380377
// enum layout optimisation is being applied.
381-
(Adt(..), _) if is_primitive_or_pointer(b) => {
378+
(Adt(..) | Pat(..), _) if is_primitive_or_pointer(b) => {
382379
if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) {
383380
a_inner == b
384381
} else {
385382
false
386383
}
387384
}
388-
(_, Adt(..)) if is_primitive_or_pointer(a) => {
385+
(_, Adt(..) | Pat(..)) if is_primitive_or_pointer(a) => {
389386
if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) {
390387
b_inner == a
391388
} else {

‎compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#![feature(let_chains)]
3434
#![feature(rustc_attrs)]
3535
#![feature(rustdoc_internals)]
36+
#![feature(try_blocks)]
3637
#![warn(unreachable_pub)]
3738
// tidy-alphabetical-end
3839

‎compiler/rustc_lint/src/types.rs

Lines changed: 91 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,37 @@ fn ty_is_known_nonnull<'tcx>(
877877
.filter_map(|variant| transparent_newtype_field(tcx, variant))
878878
.any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode))
879879
}
880+
ty::Pat(base, pat) => {
881+
ty_is_known_nonnull(tcx, typing_env, *base, mode)
882+
|| Option::unwrap_or_default(
883+
try {
884+
match **pat {
885+
ty::PatternKind::Range { start, end, include_end } => {
886+
match (start, end) {
887+
(Some(start), None) => {
888+
start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
889+
}
890+
(Some(start), Some(end)) => {
891+
let start =
892+
start.try_to_value()?.try_to_bits(tcx, typing_env)?;
893+
let end =
894+
end.try_to_value()?.try_to_bits(tcx, typing_env)?;
895+
896+
if include_end {
897+
// This also works for negative numbers, as we just need
898+
// to ensure we aren't wrapping over zero.
899+
start > 0 && end >= start
900+
} else {
901+
start > 0 && end > start
902+
}
903+
}
904+
_ => false,
905+
}
906+
}
907+
}
908+
},
909+
)
910+
}
880911
_ => false,
881912
}
882913
}
@@ -907,9 +938,8 @@ fn get_nullable_type<'tcx>(
907938
};
908939
return get_nullable_type(tcx, typing_env, inner_field_ty);
909940
}
910-
ty::Int(ty) => Ty::new_int(tcx, ty),
911-
ty::Uint(ty) => Ty::new_uint(tcx, ty),
912-
ty::RawPtr(ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
941+
ty::Pat(base, ..) => return get_nullable_type(tcx, typing_env, base),
942+
ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => ty,
913943
// As these types are always non-null, the nullable equivalent of
914944
// `Option<T>` of these types are their raw pointer counterparts.
915945
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
@@ -965,63 +995,69 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
965995
ckind: CItemKind,
966996
) -> Option<Ty<'tcx>> {
967997
debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty);
968-
if let ty::Adt(ty_def, args) = ty.kind() {
969-
let field_ty = match &ty_def.variants().raw[..] {
970-
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
971-
([], [field]) | ([field], []) => field.ty(tcx, args),
972-
([field1], [field2]) => {
973-
let ty1 = field1.ty(tcx, args);
974-
let ty2 = field2.ty(tcx, args);
975-
976-
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
977-
ty2
978-
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
979-
ty1
980-
} else {
981-
return None;
998+
match ty.kind() {
999+
ty::Adt(ty_def, args) => {
1000+
let field_ty = match &ty_def.variants().raw[..] {
1001+
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
1002+
([], [field]) | ([field], []) => field.ty(tcx, args),
1003+
([field1], [field2]) => {
1004+
let ty1 = field1.ty(tcx, args);
1005+
let ty2 = field2.ty(tcx, args);
1006+
1007+
if is_niche_optimization_candidate(tcx, typing_env, ty1) {
1008+
ty2
1009+
} else if is_niche_optimization_candidate(tcx, typing_env, ty2) {
1010+
ty1
1011+
} else {
1012+
return None;
1013+
}
9821014
}
983-
}
1015+
_ => return None,
1016+
},
9841017
_ => return None,
985-
},
986-
_ => return None,
987-
};
1018+
};
9881019

989-
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
990-
return None;
991-
}
1020+
if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) {
1021+
return None;
1022+
}
9921023

993-
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
994-
// If the computed size for the field and the enum are different, the nonnull optimization isn't
995-
// being applied (and we've got a problem somewhere).
996-
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
997-
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
998-
bug!("improper_ctypes: Option nonnull optimization not applied?");
999-
}
1024+
// At this point, the field's type is known to be nonnull and the parent enum is Option-like.
1025+
// If the computed size for the field and the enum are different, the nonnull optimization isn't
1026+
// being applied (and we've got a problem somewhere).
1027+
let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, typing_env).ok();
1028+
if !compute_size_skeleton(ty)?.same_size(compute_size_skeleton(field_ty)?) {
1029+
bug!("improper_ctypes: Option nonnull optimization not applied?");
1030+
}
10001031

1001-
// Return the nullable type this Option-like enum can be safely represented with.
1002-
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
1003-
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
1004-
bug!("should be able to compute the layout of non-polymorphic type");
1005-
}
1032+
// Return the nullable type this Option-like enum can be safely represented with.
1033+
let field_ty_layout = tcx.layout_of(typing_env.as_query_input(field_ty));
1034+
if field_ty_layout.is_err() && !field_ty.has_non_region_param() {
1035+
bug!("should be able to compute the layout of non-polymorphic type");
1036+
}
10061037

1007-
let field_ty_abi = &field_ty_layout.ok()?.backend_repr;
1008-
if let BackendRepr::Scalar(field_ty_scalar) = field_ty_abi {
1009-
match field_ty_scalar.valid_range(&tcx) {
1010-
WrappingRange { start: 0, end }
1011-
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
1012-
{
1013-
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
1014-
}
1015-
WrappingRange { start: 1, .. } => {
1016-
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
1017-
}
1018-
WrappingRange { start, end } => {
1019-
unreachable!("Unhandled start and end range: ({}, {})", start, end)
1020-
}
1021-
};
1038+
let field_ty_abi = &field_ty_layout.ok()?.backend_repr;
1039+
if let BackendRepr::Scalar(field_ty_scalar) = field_ty_abi {
1040+
match field_ty_scalar.valid_range(&tcx) {
1041+
WrappingRange { start: 0, end }
1042+
if end == field_ty_scalar.size(&tcx).unsigned_int_max() - 1 =>
1043+
{
1044+
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
1045+
}
1046+
WrappingRange { start: 1, .. } => {
1047+
return Some(get_nullable_type(tcx, typing_env, field_ty).unwrap());
1048+
}
1049+
WrappingRange { start, end } => {
1050+
unreachable!("Unhandled start and end range: ({}, {})", start, end)
1051+
}
1052+
};
1053+
}
1054+
None
10221055
}
1056+
ty::Pat(base, pat) => match **pat {
1057+
ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, *base),
1058+
},
1059+
_ => None,
10231060
}
1024-
None
10251061
}
10261062

10271063
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
@@ -1256,11 +1292,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12561292
help: Some(fluent::lint_improper_ctypes_char_help),
12571293
},
12581294

1259-
ty::Pat(..) => FfiUnsafe {
1260-
ty,
1261-
reason: fluent::lint_improper_ctypes_pat_reason,
1262-
help: Some(fluent::lint_improper_ctypes_pat_help),
1263-
},
1295+
// It's just extra invariants on the type that you need to uphold,
1296+
// but only the base type is relevant for being representable in FFI.
1297+
ty::Pat(base, ..) => self.check_type_for_ffi(acc, base),
12641298

12651299
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
12661300
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }

‎tests/ui/lint/clashing-extern-fn.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ check-pass
22
//@ aux-build:external_extern_fn.rs
33
#![crate_type = "lib"]
4-
4+
#![feature(pattern_type_macro, pattern_types)]
55
mod redeclared_different_signature {
66
mod a {
77
extern "C" {
@@ -490,3 +490,33 @@ mod hidden_niche {
490490
}
491491
}
492492
}
493+
494+
mod pattern_types {
495+
mod a {
496+
use std::pat::pattern_type;
497+
#[repr(transparent)]
498+
struct NonZeroUsize(pattern_type!(usize is 1..));
499+
extern "C" {
500+
fn pt_non_zero_usize() -> pattern_type!(usize is 1..);
501+
fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
502+
fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
503+
//~^ WARN not FFI-safe
504+
fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
505+
fn pt_non_zero_usize_wrapper() -> NonZeroUsize;
506+
fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
507+
}
508+
}
509+
mod b {
510+
extern "C" {
511+
// If there's a clash in either of these cases you're either gaining an incorrect
512+
// invariant that the value is non-zero, or you're missing out on that invariant. Both
513+
// cases are warning for, from both a caller-convenience and optimisation perspective.
514+
fn pt_non_zero_usize() -> usize;
515+
fn pt_non_zero_usize_opt() -> usize;
516+
fn pt_non_null_ptr() -> *const ();
517+
//~^ WARN `pt_non_null_ptr` redeclared with a different signature
518+
fn pt_non_zero_usize_wrapper() -> usize;
519+
fn pt_non_zero_usize_wrapper_opt() -> usize;
520+
}
521+
}
522+
}

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
1717
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
1818
= note: enum has no representation hint
1919

20+
warning: `extern` block uses type `Option<(usize) is 0..=>`, which is not FFI-safe
21+
--> $DIR/clashing-extern-fn.rs:502:54
22+
|
23+
LL | fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
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+
2029
warning: `clash` redeclared with a different signature
2130
--> $DIR/clashing-extern-fn.rs:13:13
2231
|
@@ -258,5 +267,17 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
258267
= note: expected `unsafe extern "C" fn() -> usize`
259268
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
260269

261-
warning: 22 warnings emitted
270+
warning: `pt_non_null_ptr` redeclared with a different signature
271+
--> $DIR/clashing-extern-fn.rs:516:13
272+
|
273+
LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
274+
| ---------------------------------------------------- `pt_non_null_ptr` previously declared here
275+
...
276+
LL | fn pt_non_null_ptr() -> *const ();
277+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
278+
|
279+
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
280+
found `unsafe extern "C" fn() -> *const ()`
281+
282+
warning: 24 warnings emitted
262283

‎tests/ui/lint/lint-ctypes-enum.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ extern "C" {
9494
fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
9595
//~^ ERROR `extern` block uses type
9696
fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>); //~ ERROR `extern` block uses type
97+
fn option_u8(x: Option<u8>); //~ ERROR `extern` block uses type
9798

9899
fn result_ref_t(x: Result<&'static u8, ()>);
99100
fn result_fn_t(x: Result<extern "C" fn(), ()>);

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

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,33 @@ LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
7979
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
8080
= note: enum has no representation hint
8181

82+
error: `extern` block uses type `Option<u8>`, which is not FFI-safe
83+
--> $DIR/lint-ctypes-enum.rs:97:21
84+
|
85+
LL | fn option_u8(x: Option<u8>);
86+
| ^^^^^^^^^^ not FFI-safe
87+
|
88+
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
89+
= note: enum has no representation hint
90+
8291
error: `extern` block uses type `u128`, which is not FFI-safe
83-
--> $DIR/lint-ctypes-enum.rs:106:33
92+
--> $DIR/lint-ctypes-enum.rs:107:33
8493
|
8594
LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
8695
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
8796
|
8897
= note: 128-bit integers don't currently have a known stable ABI
8998

9099
error: `extern` block uses type `i128`, which is not FFI-safe
91-
--> $DIR/lint-ctypes-enum.rs:113:33
100+
--> $DIR/lint-ctypes-enum.rs:114:33
92101
|
93102
LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
94103
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
95104
|
96105
= note: 128-bit integers don't currently have a known stable ABI
97106

98107
error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe
99-
--> $DIR/lint-ctypes-enum.rs:118:38
108+
--> $DIR/lint-ctypes-enum.rs:119:38
100109
|
101110
LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
102111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -105,7 +114,7 @@ LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u
105114
= note: enum has no representation hint
106115

107116
error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe
108-
--> $DIR/lint-ctypes-enum.rs:120:30
117+
--> $DIR/lint-ctypes-enum.rs:121:30
109118
|
110119
LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
111120
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -114,7 +123,7 @@ LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
114123
= note: enum has no representation hint
115124

116125
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe
117-
--> $DIR/lint-ctypes-enum.rs:124:51
126+
--> $DIR/lint-ctypes-enum.rs:125:51
118127
|
119128
LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
120129
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -123,7 +132,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>,
123132
= note: enum has no representation hint
124133

125134
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe
126-
--> $DIR/lint-ctypes-enum.rs:126:53
135+
--> $DIR/lint-ctypes-enum.rs:127:53
127136
|
128137
LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
129138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -132,7 +141,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
132141
= note: enum has no representation hint
133142

134143
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe
135-
--> $DIR/lint-ctypes-enum.rs:128:51
144+
--> $DIR/lint-ctypes-enum.rs:129:51
136145
|
137146
LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
138147
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -141,7 +150,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
141150
= note: enum has no representation hint
142151

143152
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe
144-
--> $DIR/lint-ctypes-enum.rs:131:49
153+
--> $DIR/lint-ctypes-enum.rs:132:49
145154
|
146155
LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
147156
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -150,7 +159,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
150159
= note: enum has no representation hint
151160

152161
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe
153-
--> $DIR/lint-ctypes-enum.rs:133:30
162+
--> $DIR/lint-ctypes-enum.rs:134:30
154163
|
155164
LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
156165
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -159,23 +168,23 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
159168
= note: enum has no representation hint
160169

161170
error: `extern` block uses type `u128`, which is not FFI-safe
162-
--> $DIR/lint-ctypes-enum.rs:144:33
171+
--> $DIR/lint-ctypes-enum.rs:145:33
163172
|
164173
LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
165174
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
166175
|
167176
= note: 128-bit integers don't currently have a known stable ABI
168177

169178
error: `extern` block uses type `i128`, which is not FFI-safe
170-
--> $DIR/lint-ctypes-enum.rs:151:33
179+
--> $DIR/lint-ctypes-enum.rs:152:33
171180
|
172181
LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
173182
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
174183
|
175184
= note: 128-bit integers don't currently have a known stable ABI
176185

177186
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
178-
--> $DIR/lint-ctypes-enum.rs:156:38
187+
--> $DIR/lint-ctypes-enum.rs:157:38
179188
|
180189
LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
181190
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -184,7 +193,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
184193
= note: enum has no representation hint
185194

186195
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe
187-
--> $DIR/lint-ctypes-enum.rs:158:30
196+
--> $DIR/lint-ctypes-enum.rs:159:30
188197
|
189198
LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
190199
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -193,7 +202,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
193202
= note: enum has no representation hint
194203

195204
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe
196-
--> $DIR/lint-ctypes-enum.rs:162:51
205+
--> $DIR/lint-ctypes-enum.rs:163:51
197206
|
198207
LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
199208
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -202,7 +211,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8
202211
= note: enum has no representation hint
203212

204213
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe
205-
--> $DIR/lint-ctypes-enum.rs:164:53
214+
--> $DIR/lint-ctypes-enum.rs:165:53
206215
|
207216
LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
208217
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -211,7 +220,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
211220
= note: enum has no representation hint
212221

213222
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe
214-
--> $DIR/lint-ctypes-enum.rs:166:51
223+
--> $DIR/lint-ctypes-enum.rs:167:51
215224
|
216225
LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
217226
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -220,7 +229,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
220229
= note: enum has no representation hint
221230

222231
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe
223-
--> $DIR/lint-ctypes-enum.rs:169:49
232+
--> $DIR/lint-ctypes-enum.rs:170:49
224233
|
225234
LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
226235
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -229,7 +238,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
229238
= note: enum has no representation hint
230239

231240
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe
232-
--> $DIR/lint-ctypes-enum.rs:171:30
241+
--> $DIR/lint-ctypes-enum.rs:172:30
233242
|
234243
LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
235244
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -238,13 +247,13 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
238247
= note: enum has no representation hint
239248

240249
error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe
241-
--> $DIR/lint-ctypes-enum.rs:173:27
250+
--> $DIR/lint-ctypes-enum.rs:174:27
242251
|
243252
LL | fn result_unit_t_e(x: Result<(), ()>);
244253
| ^^^^^^^^^^^^^^ not FFI-safe
245254
|
246255
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
247256
= note: enum has no representation hint
248257

249-
error: aborting due to 26 previous errors
258+
error: aborting due to 27 previous errors
250259

0 commit comments

Comments
 (0)
Please sign in to comment.