mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-07 12:48:30 +00:00
Auto merge of #64359 - varkor:opaque-ty-in-extern, r=estebank
Forbid opaque types in `extern "C"` blocks Fixes #64338.
This commit is contained in:
commit
eb48d6bdee
@ -624,7 +624,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
AdtKind::Struct => {
|
AdtKind::Struct => {
|
||||||
if !def.repr.c() && !def.repr.transparent() {
|
if !def.repr.c() && !def.repr.transparent() {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this struct has unspecified layout",
|
reason: "this struct has unspecified layout",
|
||||||
help: Some("consider adding a `#[repr(C)]` or \
|
help: Some("consider adding a `#[repr(C)]` or \
|
||||||
`#[repr(transparent)]` attribute to this struct"),
|
`#[repr(transparent)]` attribute to this struct"),
|
||||||
@ -633,7 +633,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
if def.non_enum_variant().fields.is_empty() {
|
if def.non_enum_variant().fields.is_empty() {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this struct has no fields",
|
reason: "this struct has no fields",
|
||||||
help: Some("consider adding a member to this struct"),
|
help: Some("consider adding a member to this struct"),
|
||||||
};
|
};
|
||||||
@ -669,7 +669,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
AdtKind::Union => {
|
AdtKind::Union => {
|
||||||
if !def.repr.c() && !def.repr.transparent() {
|
if !def.repr.c() && !def.repr.transparent() {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this union has unspecified layout",
|
reason: "this union has unspecified layout",
|
||||||
help: Some("consider adding a `#[repr(C)]` or \
|
help: Some("consider adding a `#[repr(C)]` or \
|
||||||
`#[repr(transparent)]` attribute to this union"),
|
`#[repr(transparent)]` attribute to this union"),
|
||||||
@ -678,7 +678,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
if def.non_enum_variant().fields.is_empty() {
|
if def.non_enum_variant().fields.is_empty() {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this union has no fields",
|
reason: "this union has no fields",
|
||||||
help: Some("consider adding a field to this union"),
|
help: Some("consider adding a field to this union"),
|
||||||
};
|
};
|
||||||
@ -721,7 +721,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
// Special-case types like `Option<extern fn()>`.
|
// Special-case types like `Option<extern fn()>`.
|
||||||
if !is_repr_nullable_ptr(cx, ty, def, substs) {
|
if !is_repr_nullable_ptr(cx, ty, def, substs) {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "enum has no representation hint",
|
reason: "enum has no representation hint",
|
||||||
help: Some("consider adding a `#[repr(C)]`, \
|
help: Some("consider adding a `#[repr(C)]`, \
|
||||||
`#[repr(transparent)]`, or integer `#[repr(...)]` \
|
`#[repr(transparent)]`, or integer `#[repr(...)]` \
|
||||||
@ -750,7 +750,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
FfiPhantom(..) => {
|
FfiPhantom(..) => {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this enum contains a PhantomData field",
|
reason: "this enum contains a PhantomData field",
|
||||||
help: None,
|
help: None,
|
||||||
};
|
};
|
||||||
@ -764,13 +764,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::Char => FfiUnsafe {
|
ty::Char => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "the `char` type has no C equivalent",
|
reason: "the `char` type has no C equivalent",
|
||||||
help: Some("consider using `u32` or `libc::wchar_t` instead"),
|
help: Some("consider using `u32` or `libc::wchar_t` instead"),
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe {
|
ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "128-bit integers don't currently have a known stable ABI",
|
reason: "128-bit integers don't currently have a known stable ABI",
|
||||||
help: None,
|
help: None,
|
||||||
},
|
},
|
||||||
@ -779,25 +779,25 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe,
|
ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe,
|
||||||
|
|
||||||
ty::Slice(_) => FfiUnsafe {
|
ty::Slice(_) => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "slices have no C equivalent",
|
reason: "slices have no C equivalent",
|
||||||
help: Some("consider using a raw pointer instead"),
|
help: Some("consider using a raw pointer instead"),
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::Dynamic(..) => FfiUnsafe {
|
ty::Dynamic(..) => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "trait objects have no C equivalent",
|
reason: "trait objects have no C equivalent",
|
||||||
help: None,
|
help: None,
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::Str => FfiUnsafe {
|
ty::Str => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "string slices have no C equivalent",
|
reason: "string slices have no C equivalent",
|
||||||
help: Some("consider using `*const u8` and a length instead"),
|
help: Some("consider using `*const u8` and a length instead"),
|
||||||
},
|
},
|
||||||
|
|
||||||
ty::Tuple(..) => FfiUnsafe {
|
ty::Tuple(..) => FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "tuples have unspecified layout",
|
reason: "tuples have unspecified layout",
|
||||||
help: Some("consider using a struct instead"),
|
help: Some("consider using a struct instead"),
|
||||||
},
|
},
|
||||||
@ -811,7 +811,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
match sig.abi() {
|
match sig.abi() {
|
||||||
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty: ty,
|
ty,
|
||||||
reason: "this function pointer has Rust-specific calling convention",
|
reason: "this function pointer has Rust-specific calling convention",
|
||||||
help: Some("consider using an `extern fn(...) -> ...` \
|
help: Some("consider using an `extern fn(...) -> ...` \
|
||||||
function pointer instead"),
|
function pointer instead"),
|
||||||
@ -855,11 +855,76 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
ty::UnnormalizedProjection(..) |
|
ty::UnnormalizedProjection(..) |
|
||||||
ty::Projection(..) |
|
ty::Projection(..) |
|
||||||
ty::Opaque(..) |
|
ty::Opaque(..) |
|
||||||
ty::FnDef(..) => bug!("Unexpected type in foreign function"),
|
ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_ffi_unsafe_type_lint(
|
||||||
|
&mut self,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
sp: Span,
|
||||||
|
note: &str,
|
||||||
|
help: Option<&str>,
|
||||||
|
) {
|
||||||
|
let mut diag = self.cx.struct_span_lint(
|
||||||
|
IMPROPER_CTYPES,
|
||||||
|
sp,
|
||||||
|
&format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
|
||||||
|
);
|
||||||
|
diag.span_label(sp, "not FFI-safe");
|
||||||
|
if let Some(help) = help {
|
||||||
|
diag.help(help);
|
||||||
|
}
|
||||||
|
diag.note(note);
|
||||||
|
if let ty::Adt(def, _) = ty.sty {
|
||||||
|
if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
|
||||||
|
diag.span_note(sp, "type defined here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diag.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
||||||
|
use crate::rustc::ty::TypeFoldable;
|
||||||
|
|
||||||
|
struct ProhibitOpaqueTypes<'tcx> {
|
||||||
|
ty: Option<Ty<'tcx>>,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'tcx> {
|
||||||
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||||
|
if let ty::Opaque(..) = ty.sty {
|
||||||
|
self.ty = Some(ty);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
ty.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut visitor = ProhibitOpaqueTypes { ty: None };
|
||||||
|
ty.visit_with(&mut visitor);
|
||||||
|
if let Some(ty) = visitor.ty {
|
||||||
|
self.emit_ffi_unsafe_type_lint(
|
||||||
|
ty,
|
||||||
|
sp,
|
||||||
|
"opaque types have no C equivalent",
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
|
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
|
||||||
|
// We have to check for opaque types before `normalize_erasing_regions`,
|
||||||
|
// which will replace opaque types with their underlying concrete type.
|
||||||
|
if self.check_for_opaque_ty(sp, ty) {
|
||||||
|
// We've already emitted an error due to an opaque type.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// it is only OK to use this function because extern fns cannot have
|
// it is only OK to use this function because extern fns cannot have
|
||||||
// any generic types right now:
|
// any generic types right now:
|
||||||
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||||
@ -867,24 +932,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
|
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
|
||||||
FfiResult::FfiSafe => {}
|
FfiResult::FfiSafe => {}
|
||||||
FfiResult::FfiPhantom(ty) => {
|
FfiResult::FfiPhantom(ty) => {
|
||||||
self.cx.span_lint(IMPROPER_CTYPES,
|
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
|
||||||
sp,
|
|
||||||
&format!("`extern` block uses type `{}` which is not FFI-safe: \
|
|
||||||
composed only of PhantomData", ty));
|
|
||||||
}
|
}
|
||||||
FfiResult::FfiUnsafe { ty: unsafe_ty, reason, help } => {
|
FfiResult::FfiUnsafe { ty, reason, help } => {
|
||||||
let msg = format!("`extern` block uses type `{}` which is not FFI-safe: {}",
|
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
|
||||||
unsafe_ty, reason);
|
|
||||||
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
|
|
||||||
if let Some(s) = help {
|
|
||||||
diag.help(s);
|
|
||||||
}
|
|
||||||
if let ty::Adt(def, _) = unsafe_ty.sty {
|
|
||||||
if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
|
|
||||||
diag.span_note(sp, "type defined here");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diag.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ struct D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn foo(x: A); //~ ERROR type `A` which is not FFI-safe
|
fn foo(x: A); //~ ERROR type `A`, which is not FFI-safe
|
||||||
fn bar(x: B); //~ ERROR type `A`
|
fn bar(x: B); //~ ERROR type `A`
|
||||||
fn baz(x: C);
|
fn baz(x: C);
|
||||||
fn qux(x: A2); //~ ERROR type `A`
|
fn qux(x: A2); //~ ERROR type `A`
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
--> $DIR/issue-14309.rs:30:15
|
--> $DIR/issue-14309.rs:30:15
|
||||||
|
|
|
|
||||||
LL | fn foo(x: A);
|
LL | fn foo(x: A);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/issue-14309.rs:1:9
|
--> $DIR/issue-14309.rs:1:9
|
||||||
@ -10,6 +10,7 @@ note: lint level defined here
|
|||||||
LL | #![deny(improper_ctypes)]
|
LL | #![deny(improper_ctypes)]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-14309.rs:4:1
|
--> $DIR/issue-14309.rs:4:1
|
||||||
|
|
|
|
||||||
@ -18,13 +19,14 @@ LL | | x: i32
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
--> $DIR/issue-14309.rs:31:15
|
--> $DIR/issue-14309.rs:31:15
|
||||||
|
|
|
|
||||||
LL | fn bar(x: B);
|
LL | fn bar(x: B);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-14309.rs:4:1
|
--> $DIR/issue-14309.rs:4:1
|
||||||
|
|
|
|
||||||
@ -33,13 +35,14 @@ LL | | x: i32
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
--> $DIR/issue-14309.rs:33:15
|
--> $DIR/issue-14309.rs:33:15
|
||||||
|
|
|
|
||||||
LL | fn qux(x: A2);
|
LL | fn qux(x: A2);
|
||||||
| ^^
|
| ^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-14309.rs:4:1
|
--> $DIR/issue-14309.rs:4:1
|
||||||
|
|
|
|
||||||
@ -48,13 +51,14 @@ LL | | x: i32
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
--> $DIR/issue-14309.rs:34:16
|
--> $DIR/issue-14309.rs:34:16
|
||||||
|
|
|
|
||||||
LL | fn quux(x: B2);
|
LL | fn quux(x: B2);
|
||||||
| ^^
|
| ^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-14309.rs:4:1
|
--> $DIR/issue-14309.rs:4:1
|
||||||
|
|
|
|
||||||
@ -63,13 +67,14 @@ LL | | x: i32
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
--> $DIR/issue-14309.rs:36:16
|
--> $DIR/issue-14309.rs:36:16
|
||||||
|
|
|
|
||||||
LL | fn fred(x: D);
|
LL | fn fred(x: D);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-14309.rs:4:1
|
--> $DIR/issue-14309.rs:4:1
|
||||||
|
|
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
pub struct Foo;
|
pub struct Foo;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn foo(x: (Foo)); //~ ERROR unspecified layout
|
pub fn foo(x: (Foo)); //~ ERROR `extern` block uses type `Foo`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `Foo`, which is not FFI-safe
|
||||||
--> $DIR/issue-16250.rs:6:20
|
--> $DIR/issue-16250.rs:6:20
|
||||||
|
|
|
|
||||||
LL | pub fn foo(x: (Foo));
|
LL | pub fn foo(x: (Foo));
|
||||||
| ^^^
|
| ^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/issue-16250.rs:1:9
|
--> $DIR/issue-16250.rs:1:9
|
||||||
@ -11,6 +11,7 @@ LL | #![deny(warnings)]
|
|||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
= note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]`
|
= note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]`
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/issue-16250.rs:3:1
|
--> $DIR/issue-16250.rs:3:1
|
||||||
|
|
|
|
||||||
|
@ -36,36 +36,37 @@ struct Rust<T>(T);
|
|||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn zf(x: Z);
|
fn zf(x: Z);
|
||||||
fn uf(x: U); //~ ERROR enum has no representation hint
|
fn uf(x: U); //~ ERROR `extern` block uses type `U`
|
||||||
fn bf(x: B); //~ ERROR enum has no representation hint
|
fn bf(x: B); //~ ERROR `extern` block uses type `B`
|
||||||
fn tf(x: T); //~ ERROR enum has no representation hint
|
fn tf(x: T); //~ ERROR `extern` block uses type `T`
|
||||||
fn repr_c(x: ReprC);
|
fn repr_c(x: ReprC);
|
||||||
fn repr_u8(x: U8);
|
fn repr_u8(x: U8);
|
||||||
fn repr_isize(x: Isize);
|
fn repr_isize(x: Isize);
|
||||||
fn option_ref(x: Option<&'static u8>);
|
fn option_ref(x: Option<&'static u8>);
|
||||||
fn option_fn(x: Option<extern "C" fn()>);
|
fn option_fn(x: Option<extern "C" fn()>);
|
||||||
fn nonnull(x: Option<std::ptr::NonNull<u8>>);
|
fn nonnull(x: Option<std::ptr::NonNull<u8>>);
|
||||||
fn unique(x: Option<std::ptr::Unique<u8>>); //~ ERROR enum has no representation hint
|
fn unique(x: Option<std::ptr::Unique<u8>>);
|
||||||
|
//~^ ERROR `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>`
|
||||||
fn nonzero_u8(x: Option<num::NonZeroU8>);
|
fn nonzero_u8(x: Option<num::NonZeroU8>);
|
||||||
fn nonzero_u16(x: Option<num::NonZeroU16>);
|
fn nonzero_u16(x: Option<num::NonZeroU16>);
|
||||||
fn nonzero_u32(x: Option<num::NonZeroU32>);
|
fn nonzero_u32(x: Option<num::NonZeroU32>);
|
||||||
fn nonzero_u64(x: Option<num::NonZeroU64>);
|
fn nonzero_u64(x: Option<num::NonZeroU64>);
|
||||||
fn nonzero_u128(x: Option<num::NonZeroU128>);
|
fn nonzero_u128(x: Option<num::NonZeroU128>);
|
||||||
//~^ ERROR 128-bit integers don't currently have a known stable ABI
|
//~^ ERROR `extern` block uses type `u128`
|
||||||
fn nonzero_usize(x: Option<num::NonZeroUsize>);
|
fn nonzero_usize(x: Option<num::NonZeroUsize>);
|
||||||
fn nonzero_i8(x: Option<num::NonZeroI8>);
|
fn nonzero_i8(x: Option<num::NonZeroI8>);
|
||||||
fn nonzero_i16(x: Option<num::NonZeroI16>);
|
fn nonzero_i16(x: Option<num::NonZeroI16>);
|
||||||
fn nonzero_i32(x: Option<num::NonZeroI32>);
|
fn nonzero_i32(x: Option<num::NonZeroI32>);
|
||||||
fn nonzero_i64(x: Option<num::NonZeroI64>);
|
fn nonzero_i64(x: Option<num::NonZeroI64>);
|
||||||
fn nonzero_i128(x: Option<num::NonZeroI128>);
|
fn nonzero_i128(x: Option<num::NonZeroI128>);
|
||||||
//~^ ERROR 128-bit integers don't currently have a known stable ABI
|
//~^ ERROR `extern` block uses type `i128`
|
||||||
fn nonzero_isize(x: Option<num::NonZeroIsize>);
|
fn nonzero_isize(x: Option<num::NonZeroIsize>);
|
||||||
fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
|
fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
|
||||||
fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
|
fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
|
||||||
fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
||||||
//~^ ERROR enum has no representation hint
|
//~^ ERROR `extern` block uses type
|
||||||
fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR enum has no representation hint
|
fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR `extern` block uses type
|
||||||
fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR enum has no representation hint
|
fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR `extern` block uses type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() { }
|
pub fn main() {}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `U`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:39:13
|
--> $DIR/lint-ctypes-enum.rs:39:13
|
||||||
|
|
|
|
||||||
LL | fn uf(x: U);
|
LL | fn uf(x: U);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/lint-ctypes-enum.rs:3:9
|
--> $DIR/lint-ctypes-enum.rs:3:9
|
||||||
@ -10,81 +10,92 @@ note: lint level defined here
|
|||||||
LL | #![deny(improper_ctypes)]
|
LL | #![deny(improper_ctypes)]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes-enum.rs:9:1
|
--> $DIR/lint-ctypes-enum.rs:9:1
|
||||||
|
|
|
|
||||||
LL | enum U { A }
|
LL | enum U { A }
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `B`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:40:13
|
--> $DIR/lint-ctypes-enum.rs:40:13
|
||||||
|
|
|
|
||||||
LL | fn bf(x: B);
|
LL | fn bf(x: B);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes-enum.rs:10:1
|
--> $DIR/lint-ctypes-enum.rs:10:1
|
||||||
|
|
|
|
||||||
LL | enum B { C, D }
|
LL | enum B { C, D }
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `T`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:41:13
|
--> $DIR/lint-ctypes-enum.rs:41:13
|
||||||
|
|
|
|
||||||
LL | fn tf(x: T);
|
LL | fn tf(x: T);
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes-enum.rs:11:1
|
--> $DIR/lint-ctypes-enum.rs:11:1
|
||||||
|
|
|
|
||||||
LL | enum T { E, F, G }
|
LL | enum T { E, F, G }
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:48:17
|
--> $DIR/lint-ctypes-enum.rs:48:17
|
||||||
|
|
|
|
||||||
LL | fn unique(x: Option<std::ptr::Unique<u8>>);
|
LL | fn unique(x: Option<std::ptr::Unique<u8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:53:23
|
--> $DIR/lint-ctypes-enum.rs:54:23
|
||||||
|
|
|
|
||||||
LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
|
LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:60:23
|
--> $DIR/lint-ctypes-enum.rs:61:23
|
||||||
|
|
|
|
||||||
LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
|
LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:65:28
|
--> $DIR/lint-ctypes-enum.rs:66:28
|
||||||
|
|
|
|
||||||
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
|
error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes-enum.rs:67:20
|
|
||||||
|
|
|
||||||
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
|
||||||
|
|
||||||
error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
|
|
||||||
--> $DIR/lint-ctypes-enum.rs:68:20
|
--> $DIR/lint-ctypes-enum.rs:68:20
|
||||||
|
|
|
|
||||||
LL | fn no_result(x: Result<(), num::NonZeroI32>);
|
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
|
error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>`, which is not FFI-safe
|
||||||
|
--> $DIR/lint-ctypes-enum.rs:69:20
|
||||||
|
|
|
||||||
|
LL | fn no_result(x: Result<(), num::NonZeroI32>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||||
|
= note: enum has no representation hint
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![deny(improper_ctypes)]
|
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
#![allow(private_in_public)]
|
#![allow(private_in_public)]
|
||||||
|
#![deny(improper_ctypes)]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
@ -54,12 +54,13 @@ extern {
|
|||||||
pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone`
|
pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone`
|
||||||
pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
|
pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
|
||||||
pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
|
pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
|
||||||
pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
|
pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize`
|
||||||
pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of PhantomData
|
pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
|
||||||
|
//~^ ERROR uses type `ZeroSizeWithPhantomData`
|
||||||
pub fn zero_size_phantom_toplevel()
|
pub fn zero_size_phantom_toplevel()
|
||||||
-> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of PhantomData
|
-> ::std::marker::PhantomData<bool>; //~ ERROR uses type `std::marker::PhantomData<bool>`
|
||||||
pub fn fn_type(p: RustFn); //~ ERROR function pointer has Rust-specific
|
pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
|
||||||
pub fn fn_type2(p: fn()); //~ ERROR function pointer has Rust-specific
|
pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
|
||||||
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
|
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
|
||||||
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
|
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
|
||||||
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
|
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
|
||||||
|
@ -1,170 +1,201 @@
|
|||||||
error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `Foo`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:46:28
|
--> $DIR/lint-ctypes.rs:46:28
|
||||||
|
|
|
|
||||||
LL | pub fn ptr_type1(size: *const Foo);
|
LL | pub fn ptr_type1(size: *const Foo);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/lint-ctypes.rs:1:9
|
--> $DIR/lint-ctypes.rs:4:9
|
||||||
|
|
|
|
||||||
LL | #![deny(improper_ctypes)]
|
LL | #![deny(improper_ctypes)]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes.rs:24:1
|
--> $DIR/lint-ctypes.rs:24:1
|
||||||
|
|
|
|
||||||
LL | pub struct Foo;
|
LL | pub struct Foo;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `Foo`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:47:28
|
--> $DIR/lint-ctypes.rs:47:28
|
||||||
|
|
|
|
||||||
LL | pub fn ptr_type2(size: *const Foo);
|
LL | pub fn ptr_type2(size: *const Foo);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes.rs:24:1
|
--> $DIR/lint-ctypes.rs:24:1
|
||||||
|
|
|
|
||||||
LL | pub struct Foo;
|
LL | pub struct Foo;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `[u32]` which is not FFI-safe: slices have no C equivalent
|
error: `extern` block uses type `[u32]`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:48:26
|
--> $DIR/lint-ctypes.rs:48:26
|
||||||
|
|
|
|
||||||
LL | pub fn slice_type(p: &[u32]);
|
LL | pub fn slice_type(p: &[u32]);
|
||||||
| ^^^^^^
|
| ^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using a raw pointer instead
|
= help: consider using a raw pointer instead
|
||||||
|
= note: slices have no C equivalent
|
||||||
|
|
||||||
error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
|
error: `extern` block uses type `str`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:49:24
|
--> $DIR/lint-ctypes.rs:49:24
|
||||||
|
|
|
|
||||||
LL | pub fn str_type(p: &str);
|
LL | pub fn str_type(p: &str);
|
||||||
| ^^^^
|
| ^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using `*const u8` and a length instead
|
= help: consider using `*const u8` and a length instead
|
||||||
|
= note: string slices have no C equivalent
|
||||||
|
|
||||||
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:50:24
|
--> $DIR/lint-ctypes.rs:50:24
|
||||||
|
|
|
|
||||||
LL | pub fn box_type(p: Box<u32>);
|
LL | pub fn box_type(p: Box<u32>);
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
|
|
||||||
error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
|
error: `extern` block uses type `char`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:51:25
|
--> $DIR/lint-ctypes.rs:51:25
|
||||||
|
|
|
|
||||||
LL | pub fn char_type(p: char);
|
LL | pub fn char_type(p: char);
|
||||||
| ^^^^
|
| ^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using `u32` or `libc::wchar_t` instead
|
= help: consider using `u32` or `libc::wchar_t` instead
|
||||||
|
= note: the `char` type has no C equivalent
|
||||||
|
|
||||||
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:52:25
|
--> $DIR/lint-ctypes.rs:52:25
|
||||||
|
|
|
|
||||||
LL | pub fn i128_type(p: i128);
|
LL | pub fn i128_type(p: i128);
|
||||||
| ^^^^
|
| ^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `u128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:53:25
|
--> $DIR/lint-ctypes.rs:53:25
|
||||||
|
|
|
|
||||||
LL | pub fn u128_type(p: u128);
|
LL | pub fn u128_type(p: u128);
|
||||||
| ^^^^
|
| ^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `dyn std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
|
error: `extern` block uses type `dyn std::clone::Clone`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:54:26
|
--> $DIR/lint-ctypes.rs:54:26
|
||||||
|
|
|
|
||||||
LL | pub fn trait_type(p: &dyn Clone);
|
LL | pub fn trait_type(p: &dyn Clone);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: trait objects have no C equivalent
|
||||||
|
|
||||||
error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
|
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:55:26
|
--> $DIR/lint-ctypes.rs:55:26
|
||||||
|
|
|
|
||||||
LL | pub fn tuple_type(p: (i32, i32));
|
LL | pub fn tuple_type(p: (i32, i32));
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using a struct instead
|
= help: consider using a struct instead
|
||||||
|
= note: tuples have unspecified layout
|
||||||
|
|
||||||
error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
|
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:56:27
|
--> $DIR/lint-ctypes.rs:56:27
|
||||||
|
|
|
|
||||||
LL | pub fn tuple_type2(p: I32Pair);
|
LL | pub fn tuple_type2(p: I32Pair);
|
||||||
| ^^^^^^^
|
| ^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using a struct instead
|
= help: consider using a struct instead
|
||||||
|
= note: tuples have unspecified layout
|
||||||
|
|
||||||
error: `extern` block uses type `ZeroSize` which is not FFI-safe: this struct has no fields
|
error: `extern` block uses type `ZeroSize`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:57:25
|
--> $DIR/lint-ctypes.rs:57:25
|
||||||
|
|
|
|
||||||
LL | pub fn zero_size(p: ZeroSize);
|
LL | pub fn zero_size(p: ZeroSize);
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a member to this struct
|
= help: consider adding a member to this struct
|
||||||
|
= note: this struct has no fields
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/lint-ctypes.rs:20:1
|
--> $DIR/lint-ctypes.rs:20:1
|
||||||
|
|
|
|
||||||
LL | pub struct ZeroSize;
|
LL | pub struct ZeroSize;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `ZeroSizeWithPhantomData` which is not FFI-safe: composed only of PhantomData
|
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:58:33
|
--> $DIR/lint-ctypes.rs:58:33
|
||||||
|
|
|
|
||||||
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
|
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: composed only of `PhantomData`
|
||||||
|
note: type defined here
|
||||||
|
--> $DIR/lint-ctypes.rs:43:1
|
||||||
|
|
|
||||||
|
LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `extern` block uses type `std::marker::PhantomData<bool>` which is not FFI-safe: composed only of PhantomData
|
error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:60:12
|
--> $DIR/lint-ctypes.rs:61:12
|
||||||
|
|
|
|
||||||
LL | -> ::std::marker::PhantomData<bool>;
|
LL | -> ::std::marker::PhantomData<bool>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: composed only of `PhantomData`
|
||||||
|
|
||||||
error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
|
error: `extern` block uses type `fn()`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:61:23
|
--> $DIR/lint-ctypes.rs:62:23
|
||||||
|
|
|
|
||||||
LL | pub fn fn_type(p: RustFn);
|
LL | pub fn fn_type(p: RustFn);
|
||||||
| ^^^^^^
|
| ^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
||||||
|
= note: this function pointer has Rust-specific calling convention
|
||||||
|
|
||||||
error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
|
error: `extern` block uses type `fn()`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:62:24
|
--> $DIR/lint-ctypes.rs:63:24
|
||||||
|
|
|
|
||||||
LL | pub fn fn_type2(p: fn());
|
LL | pub fn fn_type2(p: fn());
|
||||||
| ^^^^
|
| ^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
= help: consider using an `extern fn(...) -> ...` function pointer instead
|
||||||
|
= note: this function pointer has Rust-specific calling convention
|
||||||
|
|
||||||
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:63:28
|
--> $DIR/lint-ctypes.rs:64:28
|
||||||
|
|
|
|
||||||
LL | pub fn fn_contained(p: RustBadRet);
|
LL | pub fn fn_contained(p: RustBadRet);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
|
|
||||||
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `i128`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:64:32
|
--> $DIR/lint-ctypes.rs:65:32
|
||||||
|
|
|
|
||||||
LL | pub fn transparent_i128(p: TransparentI128);
|
LL | pub fn transparent_i128(p: TransparentI128);
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
||||||
|
= note: 128-bit integers don't currently have a known stable ABI
|
||||||
|
|
||||||
error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
|
error: `extern` block uses type `str`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:65:31
|
--> $DIR/lint-ctypes.rs:66:31
|
||||||
|
|
|
|
||||||
LL | pub fn transparent_str(p: TransparentStr);
|
LL | pub fn transparent_str(p: TransparentStr);
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider using `*const u8` and a length instead
|
= help: consider using `*const u8` and a length instead
|
||||||
|
= note: string slices have no C equivalent
|
||||||
|
|
||||||
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
|
||||||
--> $DIR/lint-ctypes.rs:66:30
|
--> $DIR/lint-ctypes.rs:67:30
|
||||||
|
|
|
|
||||||
LL | pub fn transparent_fn(p: TransparentBadFn);
|
LL | pub fn transparent_fn(p: TransparentBadFn);
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
|
|
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||||
|
= note: this struct has unspecified layout
|
||||||
|
|
||||||
error: aborting due to 20 previous errors
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
|
16
src/test/ui/lint/opaque-ty-ffi-unsafe.rs
Normal file
16
src/test/ui/lint/opaque-ty-ffi-unsafe.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
#![deny(improper_ctypes)]
|
||||||
|
|
||||||
|
type A = impl Fn();
|
||||||
|
|
||||||
|
pub fn ret_closure() -> A {
|
||||||
|
|| {}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn a(_: A);
|
||||||
|
//~^ ERROR `extern` block uses type `A`, which is not FFI-safe
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
Normal file
15
src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error: `extern` block uses type `A`, which is not FFI-safe
|
||||||
|
--> $DIR/opaque-ty-ffi-unsafe.rs:12:17
|
||||||
|
|
|
||||||
|
LL | pub fn a(_: A);
|
||||||
|
| ^ not FFI-safe
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/opaque-ty-ffi-unsafe.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![deny(improper_ctypes)]
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
= note: opaque types have no C equivalent
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -12,7 +12,7 @@ union W {
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static FOREIGN1: U; // OK
|
static FOREIGN1: U; // OK
|
||||||
static FOREIGN2: W; //~ ERROR union has unspecified layout
|
static FOREIGN2: W; //~ ERROR `extern` block uses type `W`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: `extern` block uses type `W` which is not FFI-safe: this union has unspecified layout
|
error: `extern` block uses type `W`, which is not FFI-safe
|
||||||
--> $DIR/union-repr-c.rs:15:22
|
--> $DIR/union-repr-c.rs:15:22
|
||||||
|
|
|
|
||||||
LL | static FOREIGN2: W;
|
LL | static FOREIGN2: W;
|
||||||
| ^
|
| ^ not FFI-safe
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/union-repr-c.rs:2:9
|
--> $DIR/union-repr-c.rs:2:9
|
||||||
@ -10,6 +10,7 @@ note: lint level defined here
|
|||||||
LL | #![deny(improper_ctypes)]
|
LL | #![deny(improper_ctypes)]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
|
||||||
|
= note: this union has unspecified layout
|
||||||
note: type defined here
|
note: type defined here
|
||||||
--> $DIR/union-repr-c.rs:9:1
|
--> $DIR/union-repr-c.rs:9:1
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user