From 9f374da46781cfe2d297636fe97b2fd9647cb1d9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Sep 2019 15:39:34 -0700 Subject: [PATCH] Exempt extern "Rust" from improper_ctypes It should be fine for Rust ABIs to involve any Rust type. --- src/liballoc/alloc.rs | 2 +- src/libcore/panicking.rs | 2 +- src/librustc_lint/types.rs | 4 +++- src/test/ui/issues/issue-64593.rs | 12 ++++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issues/issue-64593.rs diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index dc7fd1adc2958..a39fcd5ad4c58 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_allocator_nounwind] pub fn handle_alloc_error(layout: Layout) -> ! { - #[allow(improper_ctypes)] + #[cfg_attr(bootstrap, allow(improper_ctypes))] extern "Rust" { #[lang = "oom"] fn oom_impl(layout: Layout) -> !; diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 15b7d69c58d24..3d2bc24bf24a5 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3 } // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe + #[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))] extern "Rust" { #[lang = "panic_impl"] fn panic_impl(pi: &PanicInfo<'_>) -> !; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 3b8c06ba154c6..40261f6d13739 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -975,7 +975,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) { let mut vis = ImproperCTypesVisitor { cx }; let abi = cx.tcx.hir().get_foreign_abi(it.hir_id); - if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic { + if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi { + // Don't worry about types in internal ABIs. + } else { match it.node { hir::ForeignItemKind::Fn(ref decl, _, _) => { vis.check_foreign_fn(it.hir_id, decl); diff --git a/src/test/ui/issues/issue-64593.rs b/src/test/ui/issues/issue-64593.rs new file mode 100644 index 0000000000000..9e787f638a998 --- /dev/null +++ b/src/test/ui/issues/issue-64593.rs @@ -0,0 +1,12 @@ +// check-pass +#![deny(improper_ctypes)] + +pub struct Error(std::num::NonZeroU32); + +extern "Rust" { + fn foo(dest: &mut [u8]) -> Result<(), Error>; +} + +fn main() { + let _ = unsafe { foo(&mut []) }; +}