Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ todo = "warn"
unimplemented = "warn"
unreachable = "warn"
panic_in_result_fn = "warn"
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
# TODO: Re-enable once every crate defines package keywords and categories.
cargo_common_metadata = "allow"
# TODO: Re-enable once the workspace dependency graph is deduplicated.
Expand Down
4 changes: 4 additions & 0 deletions libdd-common-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ serde = "1.0"
bolero = "0.13"
assert_no_alloc = "1.1.2"
function_name = "0.3.0"

[lints.clippy]
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
12 changes: 6 additions & 6 deletions libdd-common-ffi/src/array_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::Error;
use anyhow::Context;
use std::{ffi::c_void, ptr::NonNull};
use core::{ffi::c_void, ptr::NonNull};

#[derive(Debug)]
#[repr(C)]
Expand Down Expand Up @@ -300,11 +300,11 @@ pub unsafe extern "C" fn ddog_ArrayQueue_capacity(queue_ptr: &ArrayQueue) -> Arr
mod tests {
use super::*;
use bolero::TypeGenerator;
use std::sync::atomic::{AtomicUsize, Ordering};
use core::sync::atomic::{AtomicUsize, Ordering};

unsafe extern "C" fn drop_item(item: *mut c_void) -> c_void {
_ = Box::from_raw(item as *mut i32);
std::mem::zeroed()
core::mem::zeroed()
}

#[test]
Expand All @@ -313,7 +313,7 @@ mod tests {
assert!(matches!(queue_new_result, ArrayQueueNewResult::Ok(_)));
let queue_ptr = match queue_new_result {
ArrayQueueNewResult::Ok(ptr) => ptr.as_ptr(),
_ => std::ptr::null_mut(),
_ => core::ptr::null_mut(),
};
let item = Box::new(1i32);
let item_ptr = Box::into_raw(item);
Expand All @@ -335,7 +335,7 @@ mod tests {
);
let item_ptr = match result {
ArrayQueuePopResult::Ok(ptr) => ptr,
_ => std::ptr::null_mut(),
_ => core::ptr::null_mut(),
};
drop(Box::from_raw(item_ptr as *mut i32));
let result = ddog_ArrayQueue_push(queue, item3_ptr as *mut c_void);
Expand Down Expand Up @@ -438,7 +438,7 @@ mod tests {
assert!(matches!(queue_new_result, ArrayQueueNewResult::Ok(_)));
let queue_ptr = match queue_new_result {
ArrayQueueNewResult::Ok(ptr) => ptr.as_ptr(),
_ => std::ptr::null_mut(),
_ => core::ptr::null_mut(),
};
let queue = unsafe { &*queue_ptr };

Expand Down
29 changes: 16 additions & 13 deletions libdd-common-ffi/src/cstr.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use alloc::ffi::{CString as AllocCString, NulError};
use alloc::vec::Vec;
use core::ffi::CStr as CoreCStr;
use core::fmt;
use std::{
use core::{
ffi::c_char,
marker::PhantomData,
mem::{self, ManuallyDrop},
Expand All @@ -17,21 +20,21 @@ pub struct CStr<'a> {
ptr: ptr::NonNull<c_char>,
/// Length of the array, not counting the null-terminator
length: usize,
_lifetime_marker: std::marker::PhantomData<&'a c_char>,
_lifetime_marker: core::marker::PhantomData<&'a c_char>,
}

impl<'a> CStr<'a> {
pub fn from_std(s: &'a std::ffi::CStr) -> Self {
pub fn from_std(s: &'a CoreCStr) -> Self {
Self {
ptr: unsafe { ptr::NonNull::new_unchecked(s.as_ptr().cast_mut()) },
length: s.to_bytes().len(),
_lifetime_marker: std::marker::PhantomData,
_lifetime_marker: core::marker::PhantomData,
}
}

pub fn into_std(&self) -> &'a std::ffi::CStr {
pub fn into_std(&self) -> &'a CoreCStr {
unsafe {
std::ffi::CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
CoreCStr::from_bytes_with_nul_unchecked(core::slice::from_raw_parts(
self.ptr.as_ptr().cast_const().cast(),
self.length + 1,
))
Expand All @@ -56,8 +59,8 @@ impl fmt::Debug for CString {
}

impl CString {
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<Self, std::ffi::NulError> {
Ok(Self::from_std(std::ffi::CString::new(t)?))
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<Self, NulError> {
Ok(Self::from_std(AllocCString::new(t)?))
}

/// Creates a new `CString` from the given input, or returns an empty `CString`
Expand Down Expand Up @@ -99,18 +102,18 @@ impl CString {
}
}

pub fn from_std(s: std::ffi::CString) -> Self {
pub fn from_std(s: AllocCString) -> Self {
let length = s.to_bytes().len();
Self {
ptr: unsafe { ptr::NonNull::new_unchecked(s.into_raw()) },
length,
}
}

pub fn into_std(self) -> std::ffi::CString {
pub fn into_std(self) -> AllocCString {
let s = ManuallyDrop::new(self);
unsafe {
std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
AllocCString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
s.ptr.as_ptr().cast(),
s.length + 1, // +1 for the null terminator
s.length + 1, // +1 for the null terminator
Expand All @@ -123,7 +126,7 @@ impl Drop for CString {
fn drop(&mut self) {
let ptr = mem::replace(&mut self.ptr, NonNull::dangling());
drop(unsafe {
std::ffi::CString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
AllocCString::from_vec_with_nul_unchecked(Vec::from_raw_parts(
ptr.as_ptr().cast(),
self.length + 1,
self.length + 1,
Expand All @@ -138,7 +141,7 @@ mod tests {

#[test]
fn test_cstr() {
let s = std::ffi::CString::new("hello").unwrap();
let s = AllocCString::new("hello").unwrap();
let cstr = CStr::from_std(&s);
assert_eq!(cstr.into_std().to_str().unwrap(), "hello");
}
Expand Down
4 changes: 2 additions & 2 deletions libdd-common-ffi/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

use crate::slice::AsBytes;
use crate::Error;
use alloc::borrow::Cow;
use core::str::FromStr;
use hyper::http::uri::{Authority, Parts};
use libdd_common::{parse_uri, Endpoint};
use std::borrow::Cow;
use std::str::FromStr;

#[no_mangle]
#[must_use]
Expand Down
16 changes: 8 additions & 8 deletions libdd-common-ffi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::slice::{AsBytes, CharSlice};
use crate::vec::Vec;
use std::fmt::{Debug, Display, Formatter};
use core::fmt::{Debug, Display, Formatter};

/// You probably don't want to use this directly. This constant is used by `handle_panic_error` to
/// signal that something went wrong, but avoid needing any allocations to represent it.
Expand All @@ -15,7 +15,7 @@ pub(crate) const CANNOT_ALLOCATE_ERROR: Error = Error {

// This error message is used as a placeholder for errors without message -- corresponding to an
// error where we couldn't even _allocate_ the message (or some other even weirder error).
const CANNOT_ALLOCATE: &std::ffi::CStr =
const CANNOT_ALLOCATE: &core::ffi::CStr =
c"libdatadog failed: (panic) Cannot allocate error message";
const CANNOT_ALLOCATE_CHAR_SLICE: CharSlice = unsafe {
crate::Slice::from_raw_parts(CANNOT_ALLOCATE.as_ptr(), CANNOT_ALLOCATE.to_bytes().len())
Expand All @@ -40,18 +40,18 @@ impl AsRef<str> for Error {
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_ref())
}
}

impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!("Error(\"{}\")", self.as_ref()))
}
}

impl std::error::Error for Error {}
impl core::error::Error for Error {}

impl From<String> for Error {
fn from(value: String) -> Self {
Expand All @@ -63,7 +63,7 @@ impl From<String> for Error {
impl From<Error> for String {
fn from(mut value: Error) -> String {
let mut vec = Vec::default();
std::mem::swap(&mut vec, &mut value.message);
core::mem::swap(&mut vec, &mut value.message);
// Safety: .message is a String (just FFI safe).
unsafe { String::from_utf8_unchecked(vec.into()) }
}
Expand All @@ -83,8 +83,8 @@ impl From<anyhow::Error> for Error {
}
}

impl From<Box<&dyn std::error::Error>> for Error {
fn from(value: Box<&dyn std::error::Error>) -> Self {
impl From<Box<&dyn core::error::Error>> for Error {
fn from(value: Box<&dyn core::error::Error>) -> Self {
Self::from(value.to_string())
}
}
Expand Down
4 changes: 2 additions & 2 deletions libdd-common-ffi/src/handle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use std::ptr::null_mut;
use core::ptr::null_mut;

use anyhow::Context;

Expand Down Expand Up @@ -48,7 +48,7 @@ impl<T> ToInner<T> for Handle<T> {
unsafe fn take(&mut self) -> anyhow::Result<Box<T>> {
// Leaving a null will help with double-free issues that can arise in C.
// Of course, it's best to never get there in the first place!
let raw = std::mem::replace(&mut self.inner, std::ptr::null_mut());
let raw = core::mem::replace(&mut self.inner, core::ptr::null_mut());
anyhow::ensure!(
!raw.is_null(),
"inner pointer was null, indicates use after free"
Expand Down
2 changes: 2 additions & 0 deletions libdd-common-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#![cfg_attr(not(test), deny(clippy::todo))]
#![cfg_attr(not(test), deny(clippy::unimplemented))]

extern crate alloc;

mod error;

pub mod array_queue;
Expand Down
14 changes: 7 additions & 7 deletions libdd-common-ffi/src/option.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use std::fmt::Debug;
use core::fmt::Debug;

#[repr(C)]
#[derive(Debug, PartialEq, Eq)]
Expand All @@ -12,11 +12,11 @@ pub enum Option<T> {
}

impl<T> Option<T> {
pub fn to_std(self) -> std::option::Option<T> {
pub fn to_std(self) -> core::option::Option<T> {
self.into()
}

pub fn to_std_ref(&self) -> std::option::Option<&T> {
pub fn to_std_ref(&self) -> core::option::Option<&T> {
match self {
Option::Some(ref s) => Some(s),
Option::None => None,
Expand All @@ -43,7 +43,7 @@ impl<T> Option<T> {
}
}

impl<T> From<Option<T>> for std::option::Option<T> {
impl<T> From<Option<T>> for core::option::Option<T> {
fn from(o: Option<T>) -> Self {
match o {
Option::Some(s) => Some(s),
Expand All @@ -52,16 +52,16 @@ impl<T> From<Option<T>> for std::option::Option<T> {
}
}

impl<T> From<std::option::Option<T>> for Option<T> {
fn from(o: std::option::Option<T>) -> Self {
impl<T> From<core::option::Option<T>> for Option<T> {
fn from(o: core::option::Option<T>) -> Self {
match o {
Some(s) => Option::Some(s),
None => Option::None,
}
}
}

impl<T: Copy> From<&Option<T>> for std::option::Option<T> {
impl<T: Copy> From<&Option<T>> for core::option::Option<T> {
fn from(o: &Option<T>) -> Self {
match o {
Option::Some(s) => Some(*s),
Expand Down
28 changes: 14 additions & 14 deletions libdd-common-ffi/src/slice.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use alloc::borrow::Cow;
use core::ffi::c_char;
use core::fmt::{Debug, Display, Formatter};
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::slice;
use core::str::Utf8Error;
use libdd_common::error::FfiSafeErrorMessage;
use serde::ser::Error;
use serde::Serializer;
use std::borrow::Cow;
use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::os::raw::c_char;
use std::str::Utf8Error;

#[repr(C)]
#[derive(Clone, Copy, Debug)]
Expand All @@ -37,7 +37,7 @@ pub struct Slice<'a, T: 'a> {
/// # Safety
/// All strings are valid UTF-8 (enforced by using c-str literals in Rust).
unsafe impl FfiSafeErrorMessage for SliceConversionError {
fn as_ffi_str(&self) -> &'static std::ffi::CStr {
fn as_ffi_str(&self) -> &'static core::ffi::CStr {
match self {
SliceConversionError::LargeLength => c"length was too large",
SliceConversionError::NullPointer => c"null pointer with non-zero length",
Expand All @@ -46,7 +46,7 @@ unsafe impl FfiSafeErrorMessage for SliceConversionError {
}
}
impl Display for SliceConversionError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
Display::fmt(self.as_rust_str(), f)
}
}
Expand All @@ -62,7 +62,7 @@ impl<'a, T: 'a> core::ops::Deref for Slice<'a, T> {
}

impl<T: Debug> Debug for Slice<'_, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.as_slice().fmt(f)
}
}
Expand Down Expand Up @@ -106,7 +106,7 @@ pub trait AsBytes<'a> {

#[inline]
fn try_to_utf8(&self) -> Result<&'a str, Utf8Error> {
std::str::from_utf8(self.as_bytes())
core::str::from_utf8(self.as_bytes())
}

fn try_to_string(&self) -> Result<String, Utf8Error> {
Expand All @@ -127,7 +127,7 @@ pub trait AsBytes<'a> {
/// # Safety
/// Must only be used when the underlying data was already confirmed to be utf8.
unsafe fn assume_utf8(&self) -> &'a str {
std::str::from_utf8_unchecked(self.as_bytes())
core::str::from_utf8_unchecked(self.as_bytes())
}
}

Expand Down Expand Up @@ -276,8 +276,8 @@ impl<'a, T> Display for Slice<'a, T>
where
Slice<'a, T>: AsBytes<'a>,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.try_to_utf8().map_err(|_| std::fmt::Error)?)
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.try_to_utf8().map_err(|_| core::fmt::Error)?)
}
}

Expand Down Expand Up @@ -322,8 +322,8 @@ impl<'a> CharSlice<'a> {
#[cfg(test)]
mod tests {
use super::*;
use core::ptr;
use std::os::raw::c_char;
use std::ptr;

#[test]
fn slice_from_into_slice() {
Expand Down
Loading
Loading