File tree 4 files changed +38
-19
lines changed
4 files changed +38
-19
lines changed Original file line number Diff line number Diff line change @@ -1004,8 +1004,18 @@ impl RawLua {
1004
1004
}
1005
1005
1006
1006
// Same as `get_userdata_ref_type_id` but assumes the userdata is already on the stack.
1007
- pub ( crate ) unsafe fn get_userdata_type_id ( & self , idx : c_int ) -> Result < Option < TypeId > > {
1008
- self . get_userdata_type_id_inner ( self . state ( ) , idx)
1007
+ pub ( crate ) unsafe fn get_userdata_type_id < T > ( & self , idx : c_int ) -> Result < Option < TypeId > > {
1008
+ match self . get_userdata_type_id_inner ( self . state ( ) , idx) {
1009
+ Ok ( type_id) => Ok ( type_id) ,
1010
+ Err ( Error :: UserDataTypeMismatch ) if ffi:: lua_type ( self . state ( ) , idx) != ffi:: LUA_TUSERDATA => {
1011
+ // Report `FromLuaConversionError` instead
1012
+ let idx_type_name = CStr :: from_ptr ( ffi:: luaL_typename ( self . state ( ) , idx) ) ;
1013
+ let idx_type_name = idx_type_name. to_str ( ) . unwrap ( ) ;
1014
+ let message = format ! ( "expected userdata of type '{}'" , short_type_name:: <T >( ) ) ;
1015
+ Err ( Error :: from_lua_conversion ( idx_type_name, "userdata" , message) )
1016
+ }
1017
+ Err ( err) => Err ( err) ,
1018
+ }
1009
1019
}
1010
1020
1011
1021
unsafe fn get_userdata_type_id_inner (
Original file line number Diff line number Diff line change @@ -195,7 +195,7 @@ impl<T: 'static> FromLua for UserDataRef<T> {
195
195
}
196
196
197
197
unsafe fn from_stack ( idx : c_int , lua : & RawLua ) -> Result < Self > {
198
- let type_id = lua. get_userdata_type_id ( idx) ?;
198
+ let type_id = lua. get_userdata_type_id :: < T > ( idx) ?;
199
199
match type_id {
200
200
Some ( type_id) if type_id == TypeId :: of :: < T > ( ) => {
201
201
( * get_userdata :: < UserDataStorage < T > > ( lua. state ( ) , idx) ) . try_borrow_owned ( )
@@ -263,7 +263,7 @@ impl<T: 'static> FromLua for UserDataRefMut<T> {
263
263
}
264
264
265
265
unsafe fn from_stack ( idx : c_int , lua : & RawLua ) -> Result < Self > {
266
- let type_id = lua. get_userdata_type_id ( idx) ?;
266
+ let type_id = lua. get_userdata_type_id :: < T > ( idx) ?;
267
267
match type_id {
268
268
Some ( type_id) if type_id == TypeId :: of :: < T > ( ) => {
269
269
( * get_userdata :: < UserDataStorage < T > > ( lua. state ( ) , idx) ) . try_borrow_owned_mut ( )
Original file line number Diff line number Diff line change @@ -121,7 +121,7 @@ impl<T> UserDataRegistry<T> {
121
121
match target_type_id {
122
122
// This branch is for `'static` userdata that share type metatable
123
123
UserDataTypeId :: Shared ( target_type_id) => {
124
- match try_self_arg ! ( rawlua. get_userdata_type_id( self_index) ) {
124
+ match try_self_arg ! ( rawlua. get_userdata_type_id:: < T > ( self_index) ) {
125
125
Some ( self_type_id) if self_type_id == target_type_id => {
126
126
let ud = get_userdata :: < UserDataStorage < T > > ( state, self_index) ;
127
127
try_self_arg ! ( ( * ud) . try_borrow_scoped( |ud| {
@@ -175,7 +175,7 @@ impl<T> UserDataRegistry<T> {
175
175
match target_type_id {
176
176
// This branch is for `'static` userdata that share type metatable
177
177
UserDataTypeId :: Shared ( target_type_id) => {
178
- match try_self_arg ! ( rawlua. get_userdata_type_id( self_index) ) {
178
+ match try_self_arg ! ( rawlua. get_userdata_type_id:: < T > ( self_index) ) {
179
179
Some ( self_type_id) if self_type_id == target_type_id => {
180
180
let ud = get_userdata :: < UserDataStorage < T > > ( state, self_index) ;
181
181
try_self_arg ! ( ( * ud) . try_borrow_scoped_mut( |ud| {
Original file line number Diff line number Diff line change @@ -206,8 +206,8 @@ fn test_metamethods() -> Result<()> {
206
206
Ok ( ( ) )
207
207
}
208
208
209
- #[ test]
210
209
#[ cfg( feature = "lua54" ) ]
210
+ #[ test]
211
211
fn test_metamethod_close ( ) -> Result < ( ) > {
212
212
#[ derive( Clone ) ]
213
213
struct MyUserData ( Arc < AtomicI64 > ) ;
@@ -791,18 +791,27 @@ fn test_userdata_method_errors() -> Result<()> {
791
791
let lua = Lua :: new ( ) ;
792
792
793
793
let ud = lua. create_userdata ( MyUserData ( 123 ) ) ?;
794
- let res = ud. call_function :: < ( ) > ( "get_value" , ( ) ) ;
795
- let Err ( Error :: CallbackError { cause, .. } ) = res else {
796
- panic ! ( "expected CallbackError, got {res:?}" ) ;
797
- } ;
798
- assert ! ( matches!(
799
- & * cause,
800
- Error :: BadArgument {
801
- to,
802
- name,
803
- ..
804
- } if to. as_deref( ) == Some ( "MyUserData.get_value" ) && name. as_deref( ) == Some ( "self" )
805
- ) ) ;
794
+ let res = ud. call_function :: < ( ) > ( "get_value" , "not a userdata" ) ;
795
+ match res {
796
+ Err ( Error :: CallbackError { cause, .. } ) => match cause. as_ref ( ) {
797
+ Error :: BadArgument {
798
+ to,
799
+ name,
800
+ cause : cause2,
801
+ ..
802
+ } => {
803
+ assert_eq ! ( to. as_deref( ) , Some ( "MyUserData.get_value" ) ) ;
804
+ assert_eq ! ( name. as_deref( ) , Some ( "self" ) ) ;
805
+ println ! ( "{}" , cause2. to_string( ) ) ;
806
+ assert_eq ! (
807
+ cause2. to_string( ) ,
808
+ "error converting Lua string to userdata (expected userdata of type 'MyUserData')"
809
+ ) ;
810
+ }
811
+ err => panic ! ( "expected BadArgument, got {err:?}" ) ,
812
+ } ,
813
+ r => panic ! ( "expected CallbackError, got {r:?}" ) ,
814
+ }
806
815
807
816
Ok ( ( ) )
808
817
}
You can’t perform that action at this time.
0 commit comments