diff --git a/.travis.yml b/.travis.yml index ad49a0e..8c3cea3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,12 @@ language: rust -rust: - - stable - - beta - - nightly env: - RUSTFLAGS="-D warnings" +matrix: + include: + - rust: stable + - rust: beta + - rust: nightly + script: cargo test --features compiletest_rs matrix: allow_failures: - rust: nightly diff --git a/Cargo.toml b/Cargo.toml index edbb1ef..09a54ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,9 +26,11 @@ builtin-lua = ["gcc"] [dependencies] libc = { version = "0.2" } failure = { version = "0.1.1" } +compiletest_rs = { version = "0.3", optional = true } [build-dependencies] gcc = { version = "0.3.52", optional = true } [dev-dependencies] rustyline = "1.0.0" + diff --git a/src/tests/mod.rs b/src/tests/mod.rs index aaaff94..0490c7d 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -744,55 +744,3 @@ fn too_many_binds() { .is_err() ); } - -// TODO: Need to use compiletest-rs or similar to make sure these don't compile. -/* -#[test] -fn should_not_compile() { - 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").unwrap(); - touter.set("userdata", lua.create_userdata(MyUserData)).unwrap(); - let userdata = touter.get::<_, AnyUserData>("userdata").unwrap(); - userdata_ref = userdata.borrow::(); - } - - // Should not allow self borrow of lua, it can change addresses - globals.set("boom", lua.create_function(|_, _| { - lua.eval::("1 + 1", None) - })).unwrap(); - - // Should not allow Scope references to leak - struct MyUserdata(Rc<()>); - impl UserData for MyUserdata {} - - let lua = Lua::new(); - let mut r = None; - lua.scope(|scope| { - r = Some(scope.create_userdata(MyUserdata(Rc::new(()))).unwrap()); - }); - - struct Test { - field: i32, - } - - let lua = Lua::new(); - lua.scope(|scope| { - let mut test = Test { field: 0 }; - - let f = scope - .create_function(|_, ()| { - test.field = 42; - Ok(()) - }) - .unwrap(); - lua.globals().set("bad!", f).unwrap(); - }); -} -*/ diff --git a/tests/compile-fail.rs b/tests/compile-fail.rs new file mode 100644 index 0000000..66a5e41 --- /dev/null +++ b/tests/compile-fail.rs @@ -0,0 +1,20 @@ +#![cfg(feature = "compiletest_rs")] + +extern crate compiletest_rs as compiletest; + +use std::path::PathBuf; + +fn run_mode(mode: &'static str) { + let mut config = compiletest::Config::default(); + + config.mode = mode.parse().expect("Invalid mode"); + config.src_base = PathBuf::from(format!("tests/{}", mode)); + config.target_rustcflags = Some("-L target/debug -L target/debug/deps".to_string()); + + compiletest::run_tests(&config); +} + +#[test] +fn compile_test() { + run_mode("compile-fail"); +} diff --git a/tests/compile-fail/function_borrow.rs b/tests/compile-fail/function_borrow.rs new file mode 100644 index 0000000..9c53823 --- /dev/null +++ b/tests/compile-fail/function_borrow.rs @@ -0,0 +1,15 @@ +extern crate rlua; + +use rlua::*; + +fn main() { + let lua = Lua::new(); + struct Test(i32); + + let test = Test(0); + + let func = lua.create_function(|_, ()| -> Result { + //~^ error: closure may outlive the current function, but it borrows `test`, which is owned by the current function + Ok(test.0) + }); +} diff --git a/tests/compile-fail/scope_invariance.rs b/tests/compile-fail/scope_invariance.rs new file mode 100644 index 0000000..d63634e --- /dev/null +++ b/tests/compile-fail/scope_invariance.rs @@ -0,0 +1,26 @@ +extern crate rlua; + +use rlua::*; + +fn main() { + struct Test { + field: i32, + } + + let lua = Lua::new(); + lua.scope(|scope| { + let f = { + let mut test = Test { field: 0 }; + + scope + .create_function_mut(|_, ()| { + test.field = 42; + //~^ error: `test` does not live long enough + Ok(()) + }) + .unwrap() + }; + + f.call::<_, ()>(()).unwrap(); + }); +} diff --git a/tests/compile-fail/userdata_borrow.rs b/tests/compile-fail/userdata_borrow.rs new file mode 100644 index 0000000..648411f --- /dev/null +++ b/tests/compile-fail/userdata_borrow.rs @@ -0,0 +1,22 @@ +extern crate rlua; + +use rlua::*; + +fn main() { + 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").unwrap(); + touter + .set("userdata", lua.create_userdata(MyUserData).unwrap()) + .unwrap(); + let userdata = touter.get::<_, AnyUserData>("userdata").unwrap(); + userdata_ref = userdata.borrow::(); + //~^ error: `userdata` does not live long enough + } +}