I noticed this when updating the toolchain; reproducing code below. The actual code uses a different struct and isn't simply an i64; this is just a minimal reproducing example.
With rustc 1.92, this prints "ok".
With rustc 1.93, this prints:
BadArgument { to: Some("Delta.__add"), pos: 1, name: Some("self"),
cause: UserDataBorrowError }
Toggling off the send feature in Cargo.toml makes the error go away on
rustc 1.93 as well, suggesting the issue is in the Send-aware borrow
tracking path inside mlua.
The __add metamethod is registered with add_meta_method (which only
needs a shared borrow of this) and the operand is taken as
UserDataRef<Delta> (also a shared borrow). When both Lua operands refer
to the same underlying userdata (e.g. local x = d; return x + x), the
argument extraction reports a borrow conflict against the still-live
this borrow.
Adding two different userdata values of the same type works fine; only
same + same fails.
use mlua::{Lua, MetaMethod, UserData, UserDataMethods, UserDataRef};
#[derive(Clone, Copy)]
struct Delta(i64);
impl UserData for Delta {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::Add, |_, this, other: UserDataRef<Delta>| {
Ok(Delta(this.0 + other.0))
});
}
}
fn main() -> mlua::Result<()> {
let lua = Lua::new();
let globals = lua.globals();
globals.set("d1", Delta(1))?;
globals.set("d2", Delta(2))?;
// Two distinct userdata values: works on both 1.92 and 1.93.
lua.load("local r = d1 + d2 assert(r) print('distinct ok')")
.exec()?;
// Same underlying userdata on both sides: works on 1.92, fails on 1.93
// when the `send` feature is enabled.
lua.load("local r = d1 + d1 print('same ok')").exec()?;
Ok(())
}
[dependencies]
mlua = { version = "0.11", features = ["vendored", "lua54", "async", "send", "serialize"] }
I noticed this when updating the toolchain; reproducing code below. The actual code uses a different struct and isn't simply an
i64; this is just a minimal reproducing example.With rustc 1.92, this prints "ok".
With rustc 1.93, this prints:
Toggling off the
sendfeature in Cargo.toml makes the error go away onrustc 1.93 as well, suggesting the issue is in the Send-aware borrow
tracking path inside mlua.
The
__addmetamethod is registered withadd_meta_method(which onlyneeds a shared borrow of
this) and the operand is taken asUserDataRef<Delta>(also a shared borrow). When both Lua operands referto the same underlying userdata (e.g.
local x = d; return x + x), theargument extraction reports a borrow conflict against the still-live
thisborrow.Adding two different userdata values of the same type works fine; only
same + samefails.