|
3 | 3 | use cargo::core::Edition; |
4 | 4 | use cargo_test_support::compare::assert_match_exact; |
5 | 5 | use cargo_test_support::git; |
6 | | -use cargo_test_support::paths::CargoPathExt; |
| 6 | +use cargo_test_support::paths::{self, CargoPathExt}; |
7 | 7 | use cargo_test_support::registry::{Dependency, Package}; |
8 | 8 | use cargo_test_support::tools; |
9 | 9 | use cargo_test_support::{basic_manifest, is_nightly, project}; |
@@ -1597,3 +1597,82 @@ fn fix_shared_cross_workspace() { |
1597 | 1597 | &p.read_file("foo/src/shared.rs"), |
1598 | 1598 | ); |
1599 | 1599 | } |
| 1600 | + |
| 1601 | +#[cargo_test] |
| 1602 | +fn abnormal_exit() { |
| 1603 | + // rustc fails unexpectedly after applying fixes, should show some error information. |
| 1604 | + // |
| 1605 | + // This works with a proc-macro that runs three times: |
| 1606 | + // - First run (collect diagnostics pass): writes a file, exits normally. |
| 1607 | + // - Second run (verify diagnostics work): it detects the presence of the |
| 1608 | + // file, removes the file, and aborts the process. |
| 1609 | + // - Third run (collecting messages to display): file not found, exits normally. |
| 1610 | + let p = project() |
| 1611 | + .file( |
| 1612 | + "Cargo.toml", |
| 1613 | + r#" |
| 1614 | + [package] |
| 1615 | + name = "foo" |
| 1616 | + version = "0.1.0" |
| 1617 | +
|
| 1618 | + [dependencies] |
| 1619 | + pm = {path="pm"} |
| 1620 | + "#, |
| 1621 | + ) |
| 1622 | + .file( |
| 1623 | + "src/lib.rs", |
| 1624 | + r#" |
| 1625 | + pub fn f() { |
| 1626 | + let mut x = 1; |
| 1627 | + pm::crashme!(); |
| 1628 | + } |
| 1629 | + "#, |
| 1630 | + ) |
| 1631 | + .file( |
| 1632 | + "pm/Cargo.toml", |
| 1633 | + r#" |
| 1634 | + [package] |
| 1635 | + name = "pm" |
| 1636 | + version = "0.1.0" |
| 1637 | + edition = "2018" |
| 1638 | +
|
| 1639 | + [lib] |
| 1640 | + proc-macro = true |
| 1641 | + "#, |
| 1642 | + ) |
| 1643 | + .file( |
| 1644 | + "pm/src/lib.rs", |
| 1645 | + r#" |
| 1646 | + use proc_macro::TokenStream; |
| 1647 | + #[proc_macro] |
| 1648 | + pub fn crashme(_input: TokenStream) -> TokenStream { |
| 1649 | + // Use a file to succeed on the first pass, and fail on the second. |
| 1650 | + let p = std::env::var_os("ONCE_PATH").unwrap(); |
| 1651 | + let check_path = std::path::Path::new(&p); |
| 1652 | + if check_path.exists() { |
| 1653 | + eprintln!("I'm not a diagnostic."); |
| 1654 | + std::fs::remove_file(check_path).unwrap(); |
| 1655 | + std::process::abort(); |
| 1656 | + } else { |
| 1657 | + std::fs::write(check_path, "").unwrap(); |
| 1658 | + "".parse().unwrap() |
| 1659 | + } |
| 1660 | + } |
| 1661 | + "#, |
| 1662 | + ) |
| 1663 | + .build(); |
| 1664 | + |
| 1665 | + p.cargo("fix --lib --allow-no-vcs") |
| 1666 | + .env( |
| 1667 | + "ONCE_PATH", |
| 1668 | + paths::root().join("proc-macro-run-once").to_str().unwrap(), |
| 1669 | + ) |
| 1670 | + .with_stderr_contains( |
| 1671 | + "[WARNING] failed to automatically apply fixes suggested by rustc to crate `foo`", |
| 1672 | + ) |
| 1673 | + .with_stderr_contains("I'm not a diagnostic.") |
| 1674 | + // "signal: 6, SIGABRT: process abort signal" on some platforms |
| 1675 | + .with_stderr_contains("rustc exited abnormally: [..]") |
| 1676 | + .with_stderr_contains("Original diagnostics will follow.") |
| 1677 | + .run(); |
| 1678 | +} |
0 commit comments