diff --git a/shaderc-rs/src/lib.rs b/shaderc-rs/src/lib.rs index aea37ce..58251fc 100644 --- a/shaderc-rs/src/lib.rs +++ b/shaderc-rs/src/lib.rs @@ -76,6 +76,7 @@ use std::any::Any; use std::cell::RefCell; use std::ffi::{CStr, CString}; use std::panic; +use std::rc::Rc; use std::{error, fmt, ptr, result, slice, str}; /// Error. @@ -697,7 +698,7 @@ impl Drop for Compiler { pub type IncludeCallbackResult = result::Result; type BoxedIncludeCallback<'a> = - Box IncludeCallbackResult + 'a>; + Rc IncludeCallbackResult + 'a>; /// An opaque object managing options to compilation. pub struct CompileOptions<'a> { @@ -753,25 +754,6 @@ impl<'a> CompileOptions<'a> { } } - /// Returns a copy of the given compilation options object. - /// - /// Returns `Err(Error::InitializationError)` if the clone operation failed (underlying call - /// returned null). - #[allow(clippy::should_implement_trait)] - pub fn clone(&self) -> Result> { - let p = unsafe { scs::shaderc_compile_options_clone(self.raw) }; - if p.is_null() { - Err(Error::InitializationError( - "failed to clone CompileOptions".to_string(), - )) - } else { - Ok(CompileOptions { - raw: p, - include_callback_fn: None, - }) - } - } - /// Sets the target environment to `env`, affecting which warnings or errors /// will be issued. /// @@ -842,7 +824,7 @@ impl<'a> CompileOptions<'a> { { use std::mem; - let f = Box::new(f); + let f = Rc::new(f); let f_ptr = &*f as *const F; self.include_callback_fn = Some(f as BoxedIncludeCallback<'a>); unsafe { @@ -1170,6 +1152,27 @@ impl<'a> CompileOptions<'a> { } } +impl<'a> Clone for CompileOptions<'a> { + fn clone(&self) -> Self { + let p = unsafe { scs::shaderc_compile_options_clone(self.raw) }; + + // This should never happen, outside of a heap allocation failure. + // `shaderc_compile_options_clone()` is documented as being identical to + // `shaderc_compile_options_init()` when passed a NULL ptr, and there + // are no other failure conditions (it is a trivial C++ copy + // constructor). + assert!( + !p.is_null(), + "shaderc_compile_options_clone() returned NULL" + ); + + CompileOptions { + raw: p, + include_callback_fn: self.include_callback_fn.clone(), + } + } +} + impl Drop for CompileOptions<'_> { fn drop(&mut self) { unsafe { scs::shaderc_compile_options_release(self.raw) } @@ -1496,7 +1499,7 @@ void main() { my_ssbo.x = 1.0; }"; let c = Compiler::new().unwrap(); let mut options = CompileOptions::new().unwrap(); options.add_macro_definition("E", None); - let o = options.clone().unwrap(); + let o = options.clone(); let result = c .compile_into_spirv_assembly( IFDEF_E,