1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use core::{ffi::CStr, hint::unreachable_unchecked};
use crate::{LuaState, ffi};
/// Error handling functions.
impl LuaState {
/* TODO: Currently this function effectively does nothing for some reason.
/// Sets a new panic function, returning the previous one.
///
/// `panic_f` will be called when an error happens outside of a protected environment (see [`LuaState::pcall`] and [`LuaState::cpcall`]) before exiting.
/// You can avoid exiting by having `panic_f` not return.
///
/// When `panic_f` is called, the error message will be at the top of the stack.
///
/// The default panic function simply prints the error message.
///
/// Note: when running Lua within Rust, errors (treated as panics) might cause an early abort, skipping `panic_f`
#[inline]
pub fn at_panic(&self, panic_f: CFunction) -> CFunction {
unsafe { mem::transmute::<lua_CFunction, CFunction>(ffi::lua_atpanic(self.0, mem::transmute::<CFunction, lua_CFunction>(panic_f)))}
}*/
/// Triggers a Lua error using `msg` as the error message (alongside file and line information).
///
/// # Lua Errors
///
/// This function always errors intentionally.
#[inline]
pub fn error(&self, msg: &CStr) -> ! {
// SAFETY: self.0 and the two CStrs are always valid and luaL_error never returns.
unsafe {
ffi::luaL_error(self.0, c"%s".as_ptr(), msg.as_ptr());
unreachable_unchecked();
}
}
/// Triggers a Lua error with the following message (alongside file and line information):
///
/// ```text
/// bad argument #{arg_n} to '{func}' ({type_name} expected, got {arg_type})
/// ```
///
/// (`func` is retrieved from the call stack and `arg_type` is the type of the element at index `arg_n`.)
///
/// # Lua Errors
///
/// This function always errors intentionally.
pub fn type_error(&self, arg_n: i32, type_name: &CStr) -> ! {
// SAFETY: self.0 and type_name are always valid and luaL_typeerror never returns.
unsafe {
ffi::luaL_typerror(self.0, arg_n, type_name.as_ptr());
unreachable_unchecked();
}
}
/// Triggers a Lua error with the following message (alongside file and line information):
///
/// ```text
/// bad argument #{arg_n} to '{func}' ({extra_msg})
/// ```
///
/// (`func` is retrieved from the call stack.)
///
/// # Lua Errors
///
/// This function always errors intentionally.
#[inline]
pub fn arg_error(&self, arg_n: i32, extra_msg: &CStr) -> ! {
// SAFETY: self.0 and extra_msg are always valid and luaL_argerror never returns.
unsafe {
ffi::luaL_argerror(self.0, arg_n, extra_msg.as_ptr());
unreachable_unchecked();
}
}
/// Pushes onto the stack a string specifying the position of the function at the given `level`:
/// level `0` is the current running function, level `1` is the function that called the current running function, and so on.
///
/// The pushed string has the following format:
///
/// ```text
/// chunk_name:current_line:
/// ```
///
/// *(A space is appended at the end.)*
///
/// If the location of the function at the given `level` is unknown, or `level` is invalid, an empty string is pushed instead.
#[inline]
pub fn location(&mut self, level: i32) {
// SAFETY: self.0 is always valid.
unsafe { ffi::luaL_where(self.0, level); }
}
/// Triggers a Lua error, popping the top element and using it as the full error message (no file or line information is included).
///
/// If the stack is empty, a generic error message is pushed beforehand.
///
/// You probably want to use [`LuaState::error`] instead.
///
/// # Lua Errors
///
/// This function always errors intentionally.
#[inline]
pub fn raw_error(&mut self) -> ! {
if self.get_top() < 1 {
self.push_byte_string(b"(no error message specified)");
}
// SAFETY: self.0 is always valid, lua_error never returns, and the stack is not empty.
unsafe {
ffi::lua_error(self.0);
unreachable_unchecked();
}
}
}