Skip to content

Commit 1ebe097

Browse files
authored
Implement Clone for CompileOptions (#148)
Motivation: `shaderc::CompileOptions::clone()` is actually kind of awkward and not particularly useful, because its return value has the inferred lifetime parameter `'_` from the original object, rather than `'a`, so the original object must be kept around anyway. As far as I can tell, there is no reason that `shaderc::CompileOptions` could not implement the regular `Clone` trait, rather than its current special `fn clone() -> Option<Self>`. This is a breaking change, because the signature of the `Clone` trait is different in the following ways: - It returns `Self` rather than `Option<Self>`. This seems more correct because `shaderc_compile_options_clone()` cannot fail except for heap allocation failure (it calls a nothrow trivial copy constructor), which is a degenerate scenario regardless. - The lifetime parameter on the return value is `'a` rather than `'_`. This seems more correct, since the current `clone()` does not borrow from the existing object. In addition, the inner `include_callback_fn` was changed from `Box<dyn Fn(...)>` to be `Rc<dyn Fn(...)>`. This should be fine because `CompileOptions` is already `!Send` due to its raw pointer member, and the function is `Fn` rather than `FnMut`.
1 parent 65388cd commit 1ebe097

1 file changed

Lines changed: 25 additions & 22 deletions

File tree

shaderc-rs/src/lib.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ use std::any::Any;
7676
use std::cell::RefCell;
7777
use std::ffi::{CStr, CString};
7878
use std::panic;
79+
use std::rc::Rc;
7980
use std::{error, fmt, ptr, result, slice, str};
8081

8182
/// Error.
@@ -697,7 +698,7 @@ impl Drop for Compiler {
697698
pub type IncludeCallbackResult = result::Result<ResolvedInclude, String>;
698699

699700
type BoxedIncludeCallback<'a> =
700-
Box<dyn Fn(&str, IncludeType, &str, usize) -> IncludeCallbackResult + 'a>;
701+
Rc<dyn Fn(&str, IncludeType, &str, usize) -> IncludeCallbackResult + 'a>;
701702

702703
/// An opaque object managing options to compilation.
703704
pub struct CompileOptions<'a> {
@@ -753,25 +754,6 @@ impl<'a> CompileOptions<'a> {
753754
}
754755
}
755756

756-
/// Returns a copy of the given compilation options object.
757-
///
758-
/// Returns `Err(Error::InitializationError)` if the clone operation failed (underlying call
759-
/// returned null).
760-
#[allow(clippy::should_implement_trait)]
761-
pub fn clone(&self) -> Result<CompileOptions<'a>> {
762-
let p = unsafe { scs::shaderc_compile_options_clone(self.raw) };
763-
if p.is_null() {
764-
Err(Error::InitializationError(
765-
"failed to clone CompileOptions".to_string(),
766-
))
767-
} else {
768-
Ok(CompileOptions {
769-
raw: p,
770-
include_callback_fn: None,
771-
})
772-
}
773-
}
774-
775757
/// Sets the target environment to `env`, affecting which warnings or errors
776758
/// will be issued.
777759
///
@@ -842,7 +824,7 @@ impl<'a> CompileOptions<'a> {
842824
{
843825
use std::mem;
844826

845-
let f = Box::new(f);
827+
let f = Rc::new(f);
846828
let f_ptr = &*f as *const F;
847829
self.include_callback_fn = Some(f as BoxedIncludeCallback<'a>);
848830
unsafe {
@@ -1170,6 +1152,27 @@ impl<'a> CompileOptions<'a> {
11701152
}
11711153
}
11721154

1155+
impl Clone for CompileOptions<'_> {
1156+
fn clone(&self) -> Self {
1157+
let p = unsafe { scs::shaderc_compile_options_clone(self.raw) };
1158+
1159+
// This should never happen, outside of a heap allocation failure.
1160+
// `shaderc_compile_options_clone()` is documented as being identical to
1161+
// `shaderc_compile_options_init()` when passed a NULL ptr, and there
1162+
// are no other failure conditions (it is a trivial C++ copy
1163+
// constructor).
1164+
assert!(
1165+
!p.is_null(),
1166+
"shaderc_compile_options_clone() returned NULL"
1167+
);
1168+
1169+
CompileOptions {
1170+
raw: p,
1171+
include_callback_fn: self.include_callback_fn.clone(),
1172+
}
1173+
}
1174+
}
1175+
11731176
impl Drop for CompileOptions<'_> {
11741177
fn drop(&mut self) {
11751178
unsafe { scs::shaderc_compile_options_release(self.raw) }
@@ -1496,7 +1499,7 @@ void main() { my_ssbo.x = 1.0; }";
14961499
let c = Compiler::new().unwrap();
14971500
let mut options = CompileOptions::new().unwrap();
14981501
options.add_macro_definition("E", None);
1499-
let o = options.clone().unwrap();
1502+
let o = options.clone();
15001503
let result = c
15011504
.compile_into_spirv_assembly(
15021505
IFDEF_E,

0 commit comments

Comments
 (0)