diff --git a/rust/nix-expr/src/eval_state.rs b/rust/nix-expr/src/eval_state.rs index 46802d3..db7c97e 100644 --- a/rust/nix-expr/src/eval_state.rs +++ b/rust/nix-expr/src/eval_state.rs @@ -64,7 +64,10 @@ struct EvalStateRef { eval_state: NonNull, } impl EvalStateRef { - fn as_ptr(&self) -> *mut raw::EvalState { + /// # Safety + /// + /// This function is unsafe because it returns a raw pointer. The caller must ensure that the pointer is not used beyond the lifetime of the underlying [raw::EvalState]. + unsafe fn as_ptr(&self) -> *mut raw::EvalState { self.eval_state.as_ptr() } } @@ -122,7 +125,11 @@ impl EvalState { context, }) } - pub fn raw_ptr(&self) -> *mut raw::EvalState { + + /// # Safety + /// + /// This function is unsafe because it returns a raw pointer. The caller must ensure that the pointer is not used beyond the lifetime of this `EvalState`. + pub unsafe fn raw_ptr(&self) -> *mut raw::EvalState { self.eval_state.as_ptr() } pub fn store(&self) -> &Store { @@ -255,15 +262,15 @@ impl EvalState { } let attr_name = CString::new(attr_name) .with_context(|| "require_attrs_select: attrName contains null byte")?; - let v2 = unsafe { - check_call!(raw::get_attr_byname( + unsafe { + let v2 = check_call!(raw::get_attr_byname( &mut self.context, v.raw_ptr(), self.eval_state.as_ptr(), attr_name.as_ptr() - )) - }?; - Ok(Value::new(v2)) + ))?; + Ok(Value::new(v2)) + } } /// Evaluate, require that the value is an attrset, and select an attribute by name. @@ -292,7 +299,7 @@ impl EvalState { attr_name.as_ptr() )) }?; - Ok(v2.map(Value::new)) + Ok(v2.map(|x| unsafe { Value::new(x) })) } /// Create a new value containing the passed string. @@ -442,8 +449,8 @@ impl EvalState { #[doc(alias = "nix_value_call_multi")] pub fn call_multi(&mut self, f: &Value, args: &[Value]) -> Result { let value = self.new_value_uninitialized()?; - let mut args_ptrs = args.iter().map(|a| a.raw_ptr()).collect::>(); unsafe { + let mut args_ptrs = args.iter().map(|a| a.raw_ptr()).collect::>(); check_call!(raw::value_call_multi( &mut self.context, self.eval_state.as_ptr(), @@ -473,13 +480,13 @@ impl EvalState { } fn new_value_uninitialized(&mut self) -> Result { - let value = unsafe { - check_call!(raw::alloc_value( + unsafe { + let value = check_call!(raw::alloc_value( &mut self.context, self.eval_state.as_ptr() - )) - }?; - Ok(Value::new(value)) + ))?; + Ok(Value::new(value)) + } } /// Create a new Nix function that is implemented by a Rust function. diff --git a/rust/nix-expr/src/value.rs b/rust/nix-expr/src/value.rs index e15d5b9..ca7b5a4 100644 --- a/rust/nix-expr/src/value.rs +++ b/rust/nix-expr/src/value.rs @@ -57,7 +57,11 @@ impl Value { /// Take ownership of a new Value. /// /// This does not call `nix_gc_incref`, but does call `nix_gc_decref` when dropped. - pub(crate) fn new(inner: *mut raw::Value) -> Self { + /// + /// # Safety + /// + /// The caller must ensure that the provided `inner` has a positive reference count, and that `inner` is not used after the returned `Value` is dropped. + pub(crate) unsafe fn new(inner: *mut raw::Value) -> Self { Value { inner: NonNull::new(inner).unwrap(), } @@ -66,13 +70,20 @@ impl Value { /// Borrow a reference to a Value. /// /// This calls `nix_gc_incref`, and the returned Value will call `nix_gc_decref` when dropped. - pub(crate) fn new_borrowed(inner: *mut raw::Value) -> Self { + /// + /// # Safety + /// + /// The caller must ensure that the provided `inner` has a positive reference count. + pub(crate) unsafe fn new_borrowed(inner: *mut raw::Value) -> Self { let v = Value::new(inner); unsafe { raw::value_incref(null_mut(), inner) }; v } - pub(crate) fn raw_ptr(&self) -> *mut raw::Value { + /// # Safety + /// + /// The caller must ensure that the returned pointer is not used after the `Value` is dropped. + pub(crate) unsafe fn raw_ptr(&self) -> *mut raw::Value { self.inner.as_ptr() } } diff --git a/rust/nix-store/src/store.rs b/rust/nix-store/src/store.rs index dc6c9cc..d1d5a72 100644 --- a/rust/nix-store/src/store.rs +++ b/rust/nix-store/src/store.rs @@ -24,7 +24,10 @@ struct StoreRef { inner: NonNull, } impl StoreRef { - pub fn ptr(&self) -> *mut raw::Store { + /// # Safety + /// + /// The returned pointer is only valid as long as the `StoreRef` is alive. + pub unsafe fn ptr(&self) -> *mut raw::Store { self.inner.as_ptr() } } @@ -157,7 +160,10 @@ impl Store { Ok(store) } - pub fn raw_ptr(&self) -> *mut raw::Store { + /// # Safety + /// + /// The returned pointer is only valid as long as the `Store` is alive. + pub unsafe fn raw_ptr(&self) -> *mut raw::Store { self.inner.ptr() }