diff --git a/library/std/build.rs b/library/std/build.rs index 83073cc77dd..04bfed12153 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -16,6 +16,9 @@ fn main() { } else if target.contains("freebsd") { println!("cargo:rustc-link-lib=execinfo"); println!("cargo:rustc-link-lib=pthread"); + if env::var("RUST_STD_FREEBSD_12_ABI").is_ok() { + println!("cargo:rustc-cfg=freebsd12"); + } } else if target.contains("netbsd") { println!("cargo:rustc-link-lib=pthread"); println!("cargo:rustc-link-lib=rt"); diff --git a/library/std/src/os/freebsd/fs.rs b/library/std/src/os/freebsd/fs.rs index 6798e0d8f44..fa440548050 100644 --- a/library/std/src/os/freebsd/fs.rs +++ b/library/std/src/os/freebsd/fs.rs @@ -74,7 +74,14 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { - unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } + // The methods below use libc::stat, so they work fine when libc is built with FreeBSD 12 ABI. + // This method would just return nonsense. + #[cfg(freebsd12)] + panic!("as_raw_stat not supported with FreeBSD 12 ABI"); + #[cfg(not(freebsd12))] + unsafe { + &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) + } } fn st_dev(&self) -> u64 { self.as_inner().as_inner().st_dev as u64 @@ -136,6 +143,11 @@ impl MetadataExt for Metadata { fn st_flags(&self) -> u32 { self.as_inner().as_inner().st_flags as u32 } + #[cfg(freebsd12)] + fn st_lspare(&self) -> u32 { + panic!("st_lspare not supported with FreeBSD 12 ABI"); + } + #[cfg(not(freebsd12))] fn st_lspare(&self) -> u32 { self.as_inner().as_inner().st_lspare as u32 }