Add compile_fail tests
This commit is contained in:
parent
6f42a6cca9
commit
551e4f1f87
|
@ -7,7 +7,7 @@ description = "High level bindings to Lua 5.1 / LuaJIT / Lua 5.3"
|
||||||
repository = "https://github.com/khvzak/mlua"
|
repository = "https://github.com/khvzak/mlua"
|
||||||
documentation = "https://docs.rs/mlua"
|
documentation = "https://docs.rs/mlua"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["lua"]
|
keywords = ["lua", "luajit"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
# [badges]
|
# [badges]
|
||||||
|
@ -34,6 +34,7 @@ pkg-config = { version = "0.3.11" }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustyline = "5.0"
|
rustyline = "5.0"
|
||||||
criterion = "0.2.0"
|
criterion = "0.2.0"
|
||||||
|
trybuild = "1.0"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "benchmark"
|
name = "benchmark"
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#[test]
|
||||||
|
fn test_compile_fail() {
|
||||||
|
let t = trybuild::TestCases::new();
|
||||||
|
t.compile_fail("tests/compile_fail/*.rs");
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
use mlua::{Lua, Result};
|
||||||
|
|
||||||
|
struct Test(i32);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let test = Test(0);
|
||||||
|
|
||||||
|
let lua = Lua::new();
|
||||||
|
let _ = lua.create_function(|_, ()| -> Result<i32> {
|
||||||
|
Ok(test.0)
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0373]: closure may outlive the current function, but it borrows `test`, which is owned by the current function
|
||||||
|
--> $DIR/function_borrow.rs:9:33
|
||||||
|
|
|
||||||
|
9 | let _ = lua.create_function(|_, ()| -> Result<i32> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `test`
|
||||||
|
10 | Ok(test.0)
|
||||||
|
| ---- `test` is borrowed here
|
||||||
|
|
|
||||||
|
note: function requires argument type to outlive `'static`
|
||||||
|
--> $DIR/function_borrow.rs:9:13
|
||||||
|
|
|
||||||
|
9 | let _ = lua.create_function(|_, ()| -> Result<i32> {
|
||||||
|
| _____________^
|
||||||
|
10 | | Ok(test.0)
|
||||||
|
11 | | });
|
||||||
|
| |______^
|
||||||
|
help: to force the closure to take ownership of `test` (and any other referenced variables), use the `move` keyword
|
||||||
|
|
|
||||||
|
9 | let _ = lua.create_function(move |_, ()| -> Result<i32> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
@ -0,0 +1,8 @@
|
||||||
|
use std::panic::catch_unwind;
|
||||||
|
|
||||||
|
use mlua::Lua;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
catch_unwind(|| lua.create_table().unwrap());
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/lua_norefunwindsafe.rs:7:5
|
||||||
|
|
|
||||||
|
7 | catch_unwind(|| lua.create_table().unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::UnsafeCell<()>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
||||||
|
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<mlua::lua::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/lua_norefunwindsafe.rs:7:5
|
||||||
|
|
|
||||||
|
7 | catch_unwind(|| lua.create_table().unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<mlua::lua::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::cell::RefCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `std::sync::Arc<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
||||||
|
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/lua_norefunwindsafe.rs:7:5
|
||||||
|
|
|
||||||
|
7 | catch_unwind(|| lua.create_table().unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<isize>`
|
||||||
|
= note: required because it appears within the type `std::cell::Cell<isize>`
|
||||||
|
= note: required because it appears within the type `std::cell::RefCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `std::sync::Arc<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
|
@ -0,0 +1,9 @@
|
||||||
|
use std::panic::catch_unwind;
|
||||||
|
|
||||||
|
use mlua::Lua;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
let table = lua.create_table().unwrap();
|
||||||
|
catch_unwind(move || table.set("a", "b").unwrap());
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/ref_nounwindsafe.rs:8:5
|
||||||
|
|
|
||||||
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::UnsafeCell<()>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `mlua::types::LuaRef<'_>`
|
||||||
|
= note: required because it appears within the type `mlua::table::Table<'_>`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
||||||
|
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<mlua::lua::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/ref_nounwindsafe.rs:8:5
|
||||||
|
|
|
||||||
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<mlua::lua::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::cell::RefCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `std::sync::Arc<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `mlua::types::LuaRef<'_>`
|
||||||
|
= note: required because it appears within the type `mlua::table::Table<'_>`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
||||||
|
|
||||||
|
error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
--> $DIR/ref_nounwindsafe.rs:8:5
|
||||||
|
|
|
||||||
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
|
||||||
|
| ^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
|
|
|
||||||
|
= help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<isize>`
|
||||||
|
= note: required because it appears within the type `std::cell::Cell<isize>`
|
||||||
|
= note: required because it appears within the type `std::cell::RefCell<mlua::lua::ExtraData>`
|
||||||
|
= note: required because it appears within the type `std::marker::PhantomData<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `std::sync::Arc<std::cell::RefCell<mlua::lua::ExtraData>>`
|
||||||
|
= note: required because it appears within the type `mlua::lua::Lua`
|
||||||
|
= note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua`
|
||||||
|
= note: required because it appears within the type `mlua::types::LuaRef<'_>`
|
||||||
|
= note: required because it appears within the type `mlua::table::Table<'_>`
|
||||||
|
= note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]`
|
||||||
|
= note: required by `std::panic::catch_unwind`
|
|
@ -0,0 +1,22 @@
|
||||||
|
use mlua::{Lua, Table, Result};
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let mut inner: Option<Table> = None;
|
||||||
|
let f = scope
|
||||||
|
.create_function_mut(move |lua, t: Table| {
|
||||||
|
if let Some(old) = inner.take() {
|
||||||
|
// Access old callback `Lua`.
|
||||||
|
}
|
||||||
|
inner = Some(t);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
f.call::<_, ()>(lua.create_table()?)?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
|
||||||
|
--> $DIR/scope_callback_capture.rs:12:14
|
||||||
|
|
|
||||||
|
12 | .create_function_mut(move |lua, t: Table| {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 9:15...
|
||||||
|
--> $DIR/scope_callback_capture.rs:9:15
|
||||||
|
|
|
||||||
|
9 | lua.scope(|scope| -> Result<()> {
|
||||||
|
| _______________^
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(move |lua, t: Table| {
|
||||||
|
... |
|
||||||
|
20 | | Ok(())
|
||||||
|
21 | | });
|
||||||
|
| |_____^
|
||||||
|
note: ...so that reference does not outlive borrowed content
|
||||||
|
--> $DIR/scope_callback_capture.rs:11:17
|
||||||
|
|
|
||||||
|
11 | let f = scope
|
||||||
|
| ^^^^^
|
||||||
|
note: but, the lifetime must be valid for the method call at 9:5...
|
||||||
|
--> $DIR/scope_callback_capture.rs:9:5
|
||||||
|
|
|
||||||
|
9 | / lua.scope(|scope| -> Result<()> {
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(move |lua, t: Table| {
|
||||||
|
... |
|
||||||
|
20 | | Ok(())
|
||||||
|
21 | | });
|
||||||
|
| |______^
|
||||||
|
note: ...so that a type/lifetime parameter is in scope here
|
||||||
|
--> $DIR/scope_callback_capture.rs:9:5
|
||||||
|
|
|
||||||
|
9 | / lua.scope(|scope| -> Result<()> {
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(move |lua, t: Table| {
|
||||||
|
... |
|
||||||
|
20 | | Ok(())
|
||||||
|
21 | | });
|
||||||
|
| |______^
|
|
@ -0,0 +1,19 @@
|
||||||
|
use mlua::{Lua, Table, Result};
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let mut inner: Option<Table> = None;
|
||||||
|
let f = scope
|
||||||
|
.create_function_mut(|_, t: Table| {
|
||||||
|
inner = Some(t);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
f.call::<_, ()>(lua.create_table()?)?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
|
||||||
|
--> $DIR/scope_callback_inner.rs:12:14
|
||||||
|
|
|
||||||
|
12 | .create_function_mut(|_, t: Table| {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 9:15...
|
||||||
|
--> $DIR/scope_callback_inner.rs:9:15
|
||||||
|
|
|
||||||
|
9 | lua.scope(|scope| -> Result<()> {
|
||||||
|
| _______________^
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(|_, t: Table| {
|
||||||
|
... |
|
||||||
|
17 | | Ok(())
|
||||||
|
18 | | });
|
||||||
|
| |_____^
|
||||||
|
note: ...so that reference does not outlive borrowed content
|
||||||
|
--> $DIR/scope_callback_inner.rs:11:17
|
||||||
|
|
|
||||||
|
11 | let f = scope
|
||||||
|
| ^^^^^
|
||||||
|
note: but, the lifetime must be valid for the method call at 9:5...
|
||||||
|
--> $DIR/scope_callback_inner.rs:9:5
|
||||||
|
|
|
||||||
|
9 | / lua.scope(|scope| -> Result<()> {
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(|_, t: Table| {
|
||||||
|
... |
|
||||||
|
17 | | Ok(())
|
||||||
|
18 | | });
|
||||||
|
| |______^
|
||||||
|
note: ...so that a type/lifetime parameter is in scope here
|
||||||
|
--> $DIR/scope_callback_inner.rs:9:5
|
||||||
|
|
|
||||||
|
9 | / lua.scope(|scope| -> Result<()> {
|
||||||
|
10 | | let mut inner: Option<Table> = None;
|
||||||
|
11 | | let f = scope
|
||||||
|
12 | | .create_function_mut(|_, t: Table| {
|
||||||
|
... |
|
||||||
|
17 | | Ok(())
|
||||||
|
18 | | });
|
||||||
|
| |______^
|
|
@ -0,0 +1,19 @@
|
||||||
|
use mlua::{Lua, Table, Result};
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
let mut outer: Option<Table> = None;
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let f = scope
|
||||||
|
.create_function_mut(|_, t: Table| {
|
||||||
|
outer = Some(t);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
f.call::<_, ()>(lua.create_table()?)?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
error: borrowed data cannot be stored outside of its closure
|
||||||
|
--> $DIR/scope_callback_outer.rs:11:17
|
||||||
|
|
|
||||||
|
9 | let mut outer: Option<Table> = None;
|
||||||
|
| --------- ...so that variable is valid at time of its declaration
|
||||||
|
10 | lua.scope(|scope| -> Result<()> {
|
||||||
|
| --------------------- borrowed data cannot outlive this closure
|
||||||
|
11 | let f = scope
|
||||||
|
| ^^^^^ cannot be stored outside of its closure
|
||||||
|
12 | .create_function_mut(|_, t: Table| {
|
||||||
|
| ------------------- cannot infer an appropriate lifetime...
|
|
@ -0,0 +1,23 @@
|
||||||
|
use mlua::{Lua, Result};
|
||||||
|
|
||||||
|
struct Test {
|
||||||
|
field: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let lua = Lua::new();
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let f = {
|
||||||
|
let mut test = Test { field: 0 };
|
||||||
|
|
||||||
|
scope
|
||||||
|
.create_function_mut(|_, ()| {
|
||||||
|
test.field = 42;
|
||||||
|
//~^ error: `test` does not live long enough
|
||||||
|
Ok(())
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
f.call::<_, ()>(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
error[E0373]: closure may outlive the current function, but it borrows `test`, which is owned by the current function
|
||||||
|
--> $DIR/scope_invariance.rs:14:38
|
||||||
|
|
|
||||||
|
9 | lua.scope(|scope| -> Result<()> {
|
||||||
|
| ----- has type `&mlua::scope::Scope<'_, '1>`
|
||||||
|
...
|
||||||
|
14 | .create_function_mut(|_, ()| {
|
||||||
|
| ^^^^^^^ may outlive borrowed value `test`
|
||||||
|
15 | test.field = 42;
|
||||||
|
| ---- `test` is borrowed here
|
||||||
|
|
|
||||||
|
note: function requires argument type to outlive `'1`
|
||||||
|
--> $DIR/scope_invariance.rs:13:13
|
||||||
|
|
|
||||||
|
13 | / scope
|
||||||
|
14 | | .create_function_mut(|_, ()| {
|
||||||
|
15 | | test.field = 42;
|
||||||
|
16 | | //~^ error: `test` does not live long enough
|
||||||
|
17 | | Ok(())
|
||||||
|
18 | | })?
|
||||||
|
| |__________________^
|
||||||
|
help: to force the closure to take ownership of `test` (and any other referenced variables), use the `move` keyword
|
||||||
|
|
|
||||||
|
14 | .create_function_mut(move |_, ()| {
|
||||||
|
| ^^^^^^^^^^^^
|
|
@ -0,0 +1,15 @@
|
||||||
|
use mlua::{Lua, UserData, Result};
|
||||||
|
|
||||||
|
struct MyUserData<'a>(&'a mut i32);
|
||||||
|
impl<'a> UserData for MyUserData<'a> {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut i = 1;
|
||||||
|
|
||||||
|
let lua = Lua::new();
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let _a = scope.create_nonstatic_userdata(MyUserData(&mut i))?;
|
||||||
|
let _b = scope.create_nonstatic_userdata(MyUserData(&mut i))?;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0499]: cannot borrow `i` as mutable more than once at a time
|
||||||
|
--> $DIR/scope_mutable_aliasing.rs:12:61
|
||||||
|
|
|
||||||
|
11 | let _a = scope.create_nonstatic_userdata(MyUserData(&mut i))?;
|
||||||
|
| ------ first mutable borrow occurs here
|
||||||
|
12 | let _b = scope.create_nonstatic_userdata(MyUserData(&mut i))?;
|
||||||
|
| ------------------------- ^^^^^^ second mutable borrow occurs here
|
||||||
|
| |
|
||||||
|
| first borrow later used by call
|
|
@ -0,0 +1,20 @@
|
||||||
|
use mlua::{Lua, UserData, Result};
|
||||||
|
|
||||||
|
struct MyUserData<'a>(&'a i32);
|
||||||
|
impl<'a> UserData for MyUserData<'a> {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Should not allow userdata borrow to outlive lifetime of AnyUserData handle
|
||||||
|
|
||||||
|
let igood = 1;
|
||||||
|
|
||||||
|
let lua = Lua::new();
|
||||||
|
lua.scope(|scope| -> Result<()> {
|
||||||
|
let _ugood = scope.create_nonstatic_userdata(MyUserData(&igood))?;
|
||||||
|
let _ubad = {
|
||||||
|
let ibad = 42;
|
||||||
|
scope.create_nonstatic_userdata(MyUserData(&ibad))?;
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0597]: `ibad` does not live long enough
|
||||||
|
--> $DIR/scope_userdata_borrow.rs:16:56
|
||||||
|
|
|
||||||
|
12 | lua.scope(|scope| -> Result<()> {
|
||||||
|
| ----- has type `&mlua::scope::Scope<'_, '1>`
|
||||||
|
...
|
||||||
|
16 | scope.create_nonstatic_userdata(MyUserData(&ibad))?;
|
||||||
|
| -------------------------------------------^^^^^--
|
||||||
|
| | |
|
||||||
|
| | borrowed value does not live long enough
|
||||||
|
| argument requires that `ibad` is borrowed for `'1`
|
||||||
|
17 | };
|
||||||
|
| - `ibad` dropped here while still borrowed
|
|
@ -0,0 +1,19 @@
|
||||||
|
use mlua::{AnyUserData, Lua, Table, UserData, Result};
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let lua = Lua::new();
|
||||||
|
let globals = lua.globals();
|
||||||
|
|
||||||
|
// Should not allow userdata borrow to outlive lifetime of AnyUserData handle
|
||||||
|
struct MyUserData;
|
||||||
|
impl UserData for MyUserData {};
|
||||||
|
let _userdata_ref;
|
||||||
|
{
|
||||||
|
let touter = globals.get::<_, Table>("touter")?;
|
||||||
|
touter.set("userdata", lua.create_userdata(MyUserData)?)?;
|
||||||
|
let userdata = touter.get::<_, AnyUserData>("userdata")?;
|
||||||
|
_userdata_ref = userdata.borrow::<MyUserData>();
|
||||||
|
//~^ error: `userdata` does not live long enough
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0597]: `userdata` does not live long enough
|
||||||
|
--> $DIR/userdata_borrow.rs:15:25
|
||||||
|
|
|
||||||
|
15 | _userdata_ref = userdata.borrow::<MyUserData>();
|
||||||
|
| ^^^^^^^^ borrowed value does not live long enough
|
||||||
|
16 | //~^ error: `userdata` does not live long enough
|
||||||
|
17 | }
|
||||||
|
| - `userdata` dropped here while still borrowed
|
||||||
|
18 | Ok(())
|
||||||
|
19 | }
|
||||||
|
| - borrow might be used here, when `_userdata_ref` is dropped and runs the destructor for type `std::result::Result<std::cell::Ref<'_, main::MyUserData>, mlua::error::Error>`
|
||||||
|
|
|
||||||
|
= note: values in a scope are dropped in the opposite order they are defined
|
Loading…
Reference in New Issue