Don't panic on mismatched `RegistryKey` use, instead return error
This commit is contained in:
parent
823c2deaca
commit
b056ed2c4e
|
@ -87,6 +87,8 @@ pub enum Error {
|
|||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
UserDataBorrowMutError,
|
||||
/// A `RegistryKey` produced from a different Lua state was used.
|
||||
MismatchedRegistryKey,
|
||||
/// A Rust callback returned `Err`, raising the contained `Error` as a Lua error.
|
||||
CallbackError {
|
||||
/// Lua call stack backtrace.
|
||||
|
@ -142,6 +144,9 @@ impl fmt::Display for Error {
|
|||
Error::UserDataTypeMismatch => write!(fmt, "userdata is not expected type"),
|
||||
Error::UserDataBorrowError => write!(fmt, "userdata already mutably borrowed"),
|
||||
Error::UserDataBorrowMutError => write!(fmt, "userdata already borrowed"),
|
||||
Error::MismatchedRegistryKey => {
|
||||
write!(fmt, "RegistryKey used from different Lua state")
|
||||
}
|
||||
Error::CallbackError { ref traceback, .. } => {
|
||||
write!(fmt, "callback error: {}", traceback)
|
||||
}
|
||||
|
|
24
src/lua.rs
24
src/lua.rs
|
@ -504,11 +504,9 @@ impl Lua {
|
|||
/// value previously placed by `create_registry_value`.
|
||||
pub fn registry_value<'lua, T: FromLua<'lua>>(&'lua self, key: &RegistryKey) -> Result<T> {
|
||||
unsafe {
|
||||
lua_assert!(
|
||||
self.state,
|
||||
Arc::ptr_eq(&key.drop_list, &(*self.extra()).registry_drop_list),
|
||||
"Lua instance passed RegistryKey created from a different Lua"
|
||||
);
|
||||
if !Arc::ptr_eq(&key.drop_list, &(*self.extra()).registry_drop_list) {
|
||||
return Err(Error::MismatchedRegistryKey);
|
||||
}
|
||||
|
||||
stack_err_guard(self.state, 0, || {
|
||||
check_stack(self.state, 1);
|
||||
|
@ -528,25 +526,25 @@ impl Lua {
|
|||
/// `create_registry_value`. In addition to manual `RegistryKey` removal, you can also call
|
||||
/// `expire_registry_values` to automatically remove values from the registry whose
|
||||
/// `RegistryKey`s have been dropped.
|
||||
pub fn remove_registry_value(&self, mut key: RegistryKey) {
|
||||
pub fn remove_registry_value(&self, mut key: RegistryKey) -> Result<()> {
|
||||
unsafe {
|
||||
lua_assert!(
|
||||
self.state,
|
||||
Arc::ptr_eq(&key.drop_list, &(*self.extra()).registry_drop_list),
|
||||
"Lua instance passed RegistryKey created from a different Lua"
|
||||
);
|
||||
if !Arc::ptr_eq(&key.drop_list, &(*self.extra()).registry_drop_list) {
|
||||
return Err(Error::MismatchedRegistryKey);
|
||||
}
|
||||
|
||||
ffi::luaL_unref(self.state, ffi::LUA_REGISTRYINDEX, key.registry_id);
|
||||
// Don't adding to the registry drop list when dropping the key
|
||||
key.registry_id = ffi::LUA_REFNIL;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given `RegistryKey` was created by a `Lua` which shares the underlying
|
||||
/// main state with this `Lua` instance.
|
||||
///
|
||||
/// Other than this, methods that accept a `RegistryKey` will panic if passed a `RegistryKey`
|
||||
/// that was not created with a matching `Lua` state.
|
||||
/// Other than this, methods that accept a `RegistryKey` will return
|
||||
/// `Error::MismatchedRegistryKey` if passed a `RegistryKey` that was not created with a
|
||||
/// matching `Lua` state.
|
||||
pub fn owns_registry_value(&self, key: &RegistryKey) -> bool {
|
||||
unsafe { Arc::ptr_eq(&key.drop_list, &(*self.extra()).registry_drop_list) }
|
||||
}
|
||||
|
|
|
@ -586,13 +586,15 @@ fn test_lua_registry_ownership() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mismatched_registry_key() {
|
||||
let lua1 = Lua::new();
|
||||
let lua2 = Lua::new();
|
||||
|
||||
let r = lua1.create_registry_value("hello").unwrap();
|
||||
lua2.remove_registry_value(r);
|
||||
match lua2.remove_registry_value(r) {
|
||||
Err(Error::MismatchedRegistryKey) => {}
|
||||
r => panic!("wrong result type for mismatched registry key, {:?}", r),
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Need to use compiletest-rs or similar to make sure these don't compile.
|
||||
|
|
Loading…
Reference in New Issue