@@ -937,18 +937,18 @@ pub const Lua = opaque {
937937 }
938938
939939 fn typeIsNotString (t : Lua.Type ) NotStringError {
940- return switch (t ) {
940+ switch (t ) {
941941 .number , .string = > unreachable ,
942942
943- .none = > error .NoneIsNotString ,
944- .nil = > error .NilIsNotString ,
945- .boolean = > error .BooleanIsNotString ,
946- .light_userdata = > error .LightUserdataIsNotString ,
947- .table = > error .TableIsNotString ,
948- .function = > error .FunctionIsNotString ,
949- .userdata = > error .UserdataIsNotString ,
950- .thread = > error .ThreadIsNotString ,
951- };
943+ .none = > return error .NoneIsNotString ,
944+ .nil = > return error .NilIsNotString ,
945+ .boolean = > return error .BooleanIsNotString ,
946+ .light_userdata = > return error .LightUserdataIsNotString ,
947+ .table = > return error .TableIsNotString ,
948+ .function = > return error .FunctionIsNotString ,
949+ .userdata = > return error .UserdataIsNotString ,
950+ .thread = > return error .ThreadIsNotString ,
951+ }
952952 }
953953
954954 /// Creates a new empty table and pushes it onto the stack. It is equivalent to calling `createTable` with
@@ -2364,6 +2364,32 @@ pub const Lua = opaque {
23642364 unreachable ;
23652365 }
23662366
2367+ /// Raises an error with a message like "<location>: bad argument #<arg_n> to '<func>' (<type_name> expected, got <actual_type>)",
2368+ /// where `location` is produced by `where()`, `func` is the name of the current chunk, and `actual_type` is the type
2369+ /// name of the actual argument.
2370+ ///
2371+ /// From: `int luaL_typerror(lua_State *L, int narg, const char *tname);`
2372+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_typerror
2373+ /// Stack Behavior: `[-0, +0, v]`
2374+ pub fn raiseErrorType (lua : * Lua , arg_n : i32 , type_name : ? [:0 ]const u8 ) noreturn {
2375+ _ = c .luaL_typerror (asState (lua ), arg_n , if (type_name ) | t | t .ptr else null );
2376+ unreachable ;
2377+ }
2378+
2379+ /// Pushes onto the stack a string identifying the current position of the control at the given level in the call stack.
2380+ /// Typically this string has the format: `chunkname:currentline:`.
2381+ ///
2382+ /// Level 0 is the running function, level 1 is the function that called the running function, etc.
2383+ /// This function is used to build a prefix for error messages.
2384+ ///
2385+ /// From: `void luaL_where(lua_State *L, int lvl);`
2386+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_where
2387+ /// Stack Behavior: `[-0, +1, m]`
2388+ pub fn where (lua : * Lua , level : i32 ) void {
2389+ assert (level >= 0 );
2390+ return c .luaL_where (asState (lua ), level );
2391+ }
2392+
23672393 /// Represents named functions that belong to a library that can be registered by a call to the `registerLibrary()`
23682394 /// function.
23692395 ///
@@ -4458,6 +4484,51 @@ test "raiseErrorArgument() should return correct error messages" {
44584484 try std .testing .expectEqualSlices (u8 , "bad argument #1 to '?' ((null))" , try lua .toLString (-1 ));
44594485}
44604486
4487+ test "raiseErrorType() should return correct error messages" {
4488+ const lua = try Lua .init (std .testing .allocator );
4489+ defer lua .deinit ();
4490+
4491+ const T = struct {
4492+ fn FullError (l : * Lua ) callconv (.c ) i32 {
4493+ return l .raiseErrorType (1 , "FOO" );
4494+ }
4495+ fn NullError (l : * Lua ) callconv (.c ) i32 {
4496+ return l .raiseErrorType (1 , null );
4497+ }
4498+ };
4499+
4500+ lua .pushCFunction (T .FullError );
4501+ lua .pushInteger (1 );
4502+ try std .testing .expectError (error .Runtime , lua .callProtected (1 , 1 , 0 ));
4503+ try std .testing .expectEqualSlices (u8 , "bad argument #1 to '?' (FOO expected, got number)" , try lua .toLString (-1 ));
4504+
4505+ lua .pushCFunction (T .NullError );
4506+ lua .pushInteger (1 );
4507+ try std .testing .expectError (error .Runtime , lua .callProtected (1 , 1 , 0 ));
4508+ try std .testing .expectEqualSlices (u8 , "bad argument #1 to '?' ((null) expected, got number)" , try lua .toLString (-1 ));
4509+ }
4510+
4511+ test "where() should report correct location" {
4512+ const lua = try Lua .init (std .testing .allocator );
4513+ defer lua .deinit ();
4514+
4515+ const T = struct {
4516+ fn whereFn (l : * Lua ) callconv (.c ) i32 {
4517+ l .where (1 );
4518+ return 1 ;
4519+ }
4520+ };
4521+ lua .registerFunction ("whereFn" , T .whereFn );
4522+ try lua .doString ("actual = whereFn()" );
4523+
4524+ try std .testing .expectEqual (Lua .Type .string , lua .getGlobal ("actual" ));
4525+ try std .testing .expectEqual (1 , lua .getTop ());
4526+ try std .testing .expectEqualStrings (
4527+ "[string \" actual = whereFn()\" ]:1: " ,
4528+ try lua .toLString (-1 ),
4529+ );
4530+ }
4531+
44614532test "ref and unref in user table" {
44624533 const lua = try Lua .init (std .testing .allocator );
44634534 defer lua .deinit ();
0 commit comments