summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/tests/testsuite/plugins.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/tests/testsuite/plugins.rs')
-rw-r--r--src/tools/cargo/tests/testsuite/plugins.rs421
1 files changed, 421 insertions, 0 deletions
diff --git a/src/tools/cargo/tests/testsuite/plugins.rs b/src/tools/cargo/tests/testsuite/plugins.rs
new file mode 100644
index 000000000..331ba32e0
--- /dev/null
+++ b/src/tools/cargo/tests/testsuite/plugins.rs
@@ -0,0 +1,421 @@
+//! Tests for rustc plugins.
+
+use cargo_test_support::rustc_host;
+use cargo_test_support::{basic_manifest, project};
+
+#[cargo_test(nightly, reason = "plugins are unstable")]
+fn plugin_to_the_max() {
+ let foo = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "foo_lib"
+
+ [dependencies.bar]
+ path = "../bar"
+ "#,
+ )
+ .file(
+ "src/main.rs",
+ r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+ extern crate foo_lib;
+
+ fn main() { foo_lib::foo(); }
+ "#,
+ )
+ .file(
+ "src/foo_lib.rs",
+ r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+
+ pub fn foo() {}
+ "#,
+ )
+ .build();
+ let _bar = project()
+ .at("bar")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+
+ [dependencies.baz]
+ path = "../baz"
+ "#,
+ )
+ .file(
+ "src/lib.rs",
+ r#"
+ #![feature(rustc_private)]
+
+ extern crate baz;
+ extern crate rustc_driver;
+
+ use rustc_driver::plugin::Registry;
+
+ #[no_mangle]
+ pub fn __rustc_plugin_registrar(_reg: &mut Registry) {
+ println!("{}", baz::baz());
+ }
+ "#,
+ )
+ .build();
+ let _baz = project()
+ .at("baz")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "baz"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "baz"
+ crate_type = ["dylib"]
+ "#,
+ )
+ .file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
+ .build();
+
+ foo.cargo("build").run();
+ foo.cargo("doc").run();
+}
+
+#[cargo_test(nightly, reason = "plugins are unstable")]
+fn plugin_with_dynamic_native_dependency() {
+ let build = project()
+ .at("builder")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "builder"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "builder"
+ crate-type = ["dylib"]
+ "#,
+ )
+ .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}")
+ .build();
+
+ let foo = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.bar]
+ path = "bar"
+ "#,
+ )
+ .file(
+ "src/main.rs",
+ r#"
+ #![feature(plugin)]
+ #![plugin(bar)]
+
+ fn main() {}
+ "#,
+ )
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+ build = 'build.rs'
+
+ [lib]
+ name = "bar"
+ plugin = true
+ "#,
+ )
+ .file(
+ "bar/build.rs",
+ r#"
+ use std::env;
+ use std::fs;
+ use std::path::PathBuf;
+
+ fn main() {
+ let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+ let root = PathBuf::from(env::var("BUILDER_ROOT").unwrap());
+ let file = format!("{}builder{}",
+ env::consts::DLL_PREFIX,
+ env::consts::DLL_SUFFIX);
+ let src = root.join(&file);
+ let dst = out_dir.join(&file);
+ fs::copy(src, dst).unwrap();
+ if cfg!(target_env = "msvc") {
+ fs::copy(root.join("builder.dll.lib"),
+ out_dir.join("builder.dll.lib")).unwrap();
+ }
+ println!("cargo:rustc-flags=-L {}", out_dir.display());
+ }
+ "#,
+ )
+ .file(
+ "bar/src/lib.rs",
+ r#"
+ #![feature(rustc_private)]
+
+ extern crate rustc_driver;
+ use rustc_driver::plugin::Registry;
+
+ #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))]
+ #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))]
+ extern { fn foo(); }
+
+ #[no_mangle]
+ pub fn __rustc_plugin_registrar(_reg: &mut Registry) {
+ unsafe { foo() }
+ }
+ "#,
+ )
+ .build();
+
+ build.cargo("build").run();
+
+ let root = build.root().join("target").join("debug");
+ foo.cargo("build -v").env("BUILDER_ROOT", root).run();
+}
+
+#[cargo_test]
+fn plugin_integration() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ build = "build.rs"
+
+ [lib]
+ name = "foo"
+ plugin = true
+ doctest = false
+ "#,
+ )
+ .file("build.rs", "fn main() {}")
+ .file("src/lib.rs", "")
+ .file("tests/it_works.rs", "")
+ .build();
+
+ p.cargo("test -v").run();
+}
+
+#[cargo_test]
+fn doctest_a_plugin() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies]
+ bar = { path = "bar" }
+ "#,
+ )
+ .file("src/lib.rs", "#[macro_use] extern crate bar;")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "bar"
+ plugin = true
+ "#,
+ )
+ .file("bar/src/lib.rs", "pub fn bar() {}")
+ .build();
+
+ p.cargo("test -v").run();
+}
+
+// See #1515
+#[cargo_test]
+fn native_plugin_dependency_with_custom_linker() {
+ let target = rustc_host();
+
+ let _foo = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ plugin = true
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ let bar = project()
+ .at("bar")
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.foo]
+ path = "../foo"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file(
+ ".cargo/config",
+ &format!(
+ r#"
+ [target.{}]
+ linker = "nonexistent-linker"
+ "#,
+ target
+ ),
+ )
+ .build();
+
+ bar.cargo("build --verbose")
+ .with_status(101)
+ .with_stderr_contains(
+ "\
+[COMPILING] foo v0.0.1 ([..])
+[RUNNING] `rustc [..] -C linker=nonexistent-linker [..]`
+[ERROR] [..]linker[..]
+",
+ )
+ .run();
+}
+
+#[cargo_test(nightly, reason = "requires rustc_private")]
+fn panic_abort_plugins() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [profile.dev]
+ panic = 'abort'
+
+ [dependencies]
+ bar = { path = "bar" }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ plugin = true
+ "#,
+ )
+ .file(
+ "bar/src/lib.rs",
+ r#"
+ #![feature(rustc_private)]
+ extern crate rustc_ast;
+ extern crate rustc_driver;
+ "#,
+ )
+ .build();
+
+ p.cargo("build").run();
+}
+
+#[cargo_test(nightly, reason = "requires rustc_private")]
+fn shared_panic_abort_plugins() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [profile.dev]
+ panic = 'abort'
+
+ [dependencies]
+ bar = { path = "bar" }
+ baz = { path = "baz" }
+ "#,
+ )
+ .file("src/lib.rs", "extern crate baz;")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ plugin = true
+
+ [dependencies]
+ baz = { path = "../baz" }
+ "#,
+ )
+ .file(
+ "bar/src/lib.rs",
+ r#"
+ #![feature(rustc_private)]
+ extern crate rustc_ast;
+ extern crate rustc_driver;
+ extern crate baz;
+ "#,
+ )
+ .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1"))
+ .file("baz/src/lib.rs", "")
+ .build();
+
+ p.cargo("build -v").run();
+}