Skip to content

Panic with "Failed to parse macro invocation" if expect! contains a long single-line string #59

Description

@oxalica

If the expect! macro contains a single long string without newlines, the macro will fail to self-update with UPDATE_EXPECT=1.

use expect_test::{Expect, expect};

fn check(expect: Expect) {
    expect.assert_eq(
        "the argument '--from <FROM>' is required because some dependency arguments are provided",
    );
}

#[test]
fn thetest() {
    // This is from a previous `UPDATE_EXPECT=1` run and formatted by `rustfmt`.
    check(expect![
        "the argument '--from <FROM>' is required because some dependency arguments are provided."
    ]);
}

UPDATE_EXPECT=1 cargo test on rustc 1.96.0:

Output with backtrace
---- thetest stdout ----
updating: tests/foo.rs:11:11

thread 'thetest' (500583) panicked at [..]/registry/src/index.crates.io-1949cf8c6b5b557f/expect-test-1.5.1/src/lib.rs:331:22:
Failed to parse macro invocation
stack backtrace:
   0:     0x5d286c4b8d4a - std[52919eca6bce4da3]::backtrace_rs::backtrace::libunwind::trace
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1:     0x5d286c4b8d4a - std[52919eca6bce4da3]::backtrace_rs::backtrace::trace_unsynchronized::<std[52919eca6bce4da3]::sys::backtrace::_print_fmt::{closure#1}>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14
   2:     0x5d286c4b8d4a - std[52919eca6bce4da3]::sys::backtrace::_print_fmt
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/backtrace.rs:74:9
   3:     0x5d286c4b8d4a - <<std[52919eca6bce4da3]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[18c8dd30382e7099]::fmt::Display>::fmt
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/backtrace.rs:44:26
   4:     0x5d286c4ccc7a - <core[18c8dd30382e7099]::fmt::rt::Argument>::fmt
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/fmt/rt.rs:152:76
   5:     0x5d286c4ccc7a - core[18c8dd30382e7099]::fmt::write
   6:     0x5d286c4bd6e2 - std[52919eca6bce4da3]::io::default_write_fmt::<alloc[c54872da263eaafc]::vec::Vec<u8>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/io/mod.rs:621:11
   7:     0x5d286c4bd6e2 - <alloc[c54872da263eaafc]::vec::Vec<u8> as std[52919eca6bce4da3]::io::Write>::write_fmt
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/io/mod.rs:1976:13
   8:     0x5d286c4974cf - <std[52919eca6bce4da3]::sys::backtrace::BacktraceLock>::print
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/backtrace.rs:47:9
   9:     0x5d286c4974cf - std[52919eca6bce4da3]::panicking::default_hook::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:292:27
  10:     0x5d286c4b0a39 - std[52919eca6bce4da3]::panicking::default_hook
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:316:9
  11:     0x5d286c4160dc - <alloc[c54872da263eaafc]::boxed::Box<dyn for<'a, 'b> core[18c8dd30382e7099]::ops::function::Fn<(&'a std[52919eca6bce4da3]::panic::PanicHookInfo<'b>,), Output = ()> + core[18c8dd30382e7099]::marker::Send + core[18c8dd30382e7099]::marker::Sync> as core[18c8dd30382e7099]::ops::function::Fn<(&std[52919eca6bce4da3]::panic::PanicHookInfo,)>>::call
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/alloc/src/boxed.rs:2263:9
  12:     0x5d286c4160dc - test[5975feb3c521cd7b]::test_main_with_exit_callback::<test[5975feb3c521cd7b]::test_main::{closure#0}>::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:145:21
  13:     0x5d286c4b0cb2 - <alloc[c54872da263eaafc]::boxed::Box<dyn for<'a, 'b> core[18c8dd30382e7099]::ops::function::Fn<(&'a std[52919eca6bce4da3]::panic::PanicHookInfo<'b>,), Output = ()> + core[18c8dd30382e7099]::marker::Send + core[18c8dd30382e7099]::marker::Sync> as core[18c8dd30382e7099]::ops::function::Fn<(&std[52919eca6bce4da3]::panic::PanicHookInfo,)>>::call
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/alloc/src/boxed.rs:2263:9
  14:     0x5d286c4b0cb2 - std[52919eca6bce4da3]::panicking::panic_with_hook
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:833:13
  15:     0x5d286c497588 - std[52919eca6bce4da3]::panicking::panic_handler::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:698:13
  16:     0x5d286c48c619 - std[52919eca6bce4da3]::sys::backtrace::__rust_end_short_backtrace::<std[52919eca6bce4da3]::panicking::panic_handler::{closure#0}, !>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/backtrace.rs:182:18
  17:     0x5d286c49829d - __rustc[8068f81614cfe5c]::rust_begin_unwind
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:689:5
  18:     0x5d286c4cd3cc - core[18c8dd30382e7099]::panicking::panic_fmt
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/panicking.rs:80:14
  19:     0x5d286c4cd0c4 - core[18c8dd30382e7099]::panicking::panic_display::<&str>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/panicking.rs:259:5
  20:     0x5d286c4cd0c4 - core[18c8dd30382e7099]::option::expect_failed
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/option.rs:2260:5
  21:     0x5d286c44acdb - core::option::Option<T>::expect::hbc688b1e00cc5ab3
                               at /nix/store/8bni00ig1l0rcfm20sz74k7qw5lkd95d-rust-default-1.96.0/lib/rustlib/src/rust/library/core/src/option.rs:971:21
  22:     0x5d286c4646a0 - expect_test::Expect::locate::h1d67ff9a85240e49
                               at /nix/store/b7b7g0p3mx6rjfn01pkcg19ly0qnnlzp-cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/expect-test-1.5.1/src/lib.rs:331:22
  23:     0x5d286c4624e0 - expect_test::FileRuntime::update::ha9f5e18838939ea6
                               at /nix/store/b7b7g0p3mx6rjfn01pkcg19ly0qnnlzp-cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/expect-test-1.5.1/src/lib.rs:545:26
  24:     0x5d286c464c35 - expect_test::Runtime::fail_expect::hf33b462e067f47d2
                               at /nix/store/b7b7g0p3mx6rjfn01pkcg19ly0qnnlzp-cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/expect-test-1.5.1/src/lib.rs:480:18
  25:     0x5d286c464a0b - expect_test::Expect::assert_eq::hf8d8cbfe745cd101
                               at /nix/store/b7b7g0p3mx6rjfn01pkcg19ly0qnnlzp-cargo-home/registry/src/index.crates.io-1949cf8c6b5b557f/expect-test-1.5.1/src/lib.rs:285:9
  26:     0x5d286c409eb3 - foo::check::heac00f041bee4286
                               at [..]/tests/foo.rs:4:12
  27:     0x5d286c409f28 - foo::thetest::h6b6e394759cdbdc8
                               at [..]/tests/foo.rs:11:5
  28:     0x5d286c40a057 - foo::thetest::{{closure}}::h6f56c62cf6d2382f
                               at [..]/tests/foo.rs:10:13
  29:     0x5d286c409dd6 - core::ops::function::FnOnce::call_once::h319b6d959e227d7e
                               at /nix/store/8bni00ig1l0rcfm20sz74k7qw5lkd95d-rust-default-1.96.0/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
  30:     0x5d286c40a1db - <fn() -> core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String> as core[18c8dd30382e7099]::ops::function::FnOnce<()>>::call_once
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/ops/function.rs:250:5
  31:     0x5d286c40a1db - test[5975feb3c521cd7b]::__rust_begin_short_backtrace::<core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String>, fn() -> core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:663:18
  32:     0x5d286c416bab - test[5975feb3c521cd7b]::run_test_in_process::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:686:74
  33:     0x5d286c416bab - <core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<test[5975feb3c521cd7b]::run_test_in_process::{closure#0}> as core[18c8dd30382e7099]::ops::function::FnOnce<()>>::call_once
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/panic/unwind_safe.rs:275:9
  34:     0x5d286c416bab - std[52919eca6bce4da3]::panicking::catch_unwind::do_call::<core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<test[5975feb3c521cd7b]::run_test_in_process::{closure#0}>, core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:581:40
  35:     0x5d286c416bab - std[52919eca6bce4da3]::panicking::catch_unwind::<core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String>, core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<test[5975feb3c521cd7b]::run_test_in_process::{closure#0}>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:544:19
  36:     0x5d286c416bab - std[52919eca6bce4da3]::panic::catch_unwind::<core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<test[5975feb3c521cd7b]::run_test_in_process::{closure#0}>, core[18c8dd30382e7099]::result::Result<(), alloc[c54872da263eaafc]::string::String>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panic.rs:359:14
  37:     0x5d286c416bab - test[5975feb3c521cd7b]::run_test_in_process
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:686:27
  38:     0x5d286c416bab - test[5975feb3c521cd7b]::run_test::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:607:43
  39:     0x5d286c4122c4 - test[5975feb3c521cd7b]::run_test::{closure#1}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/test/src/lib.rs:637:41
  40:     0x5d286c4122c4 - std[52919eca6bce4da3]::sys::backtrace::__rust_begin_short_backtrace::<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/backtrace.rs:166:18
  41:     0x5d286c4197b2 - std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked::<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}::{closure#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/thread/lifecycle.rs:91:13
  42:     0x5d286c4197b2 - <core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}::{closure#0}> as core[18c8dd30382e7099]::ops::function::FnOnce<()>>::call_once
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/panic/unwind_safe.rs:275:9
  43:     0x5d286c4197b2 - std[52919eca6bce4da3]::panicking::catch_unwind::do_call::<core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}::{closure#0}>, ()>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:581:40
  44:     0x5d286c4197b2 - std[52919eca6bce4da3]::panicking::catch_unwind::<(), core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}::{closure#0}>>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panicking.rs:544:19
  45:     0x5d286c4197b2 - std[52919eca6bce4da3]::panic::catch_unwind::<core[18c8dd30382e7099]::panic::unwind_safe::AssertUnwindSafe<std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}::{closure#0}>, ()>
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/panic.rs:359:14
  46:     0x5d286c4197b2 - std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked::<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/thread/lifecycle.rs:89:26
  47:     0x5d286c4197b2 - <std[52919eca6bce4da3]::thread::lifecycle::spawn_unchecked<test[5975feb3c521cd7b]::run_test::{closure#1}, ()>::{closure#1} as core[18c8dd30382e7099]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/core/src/ops/function.rs:250:5
  48:     0x5d286c4b80ff - <alloc[c54872da263eaafc]::boxed::Box<dyn core[18c8dd30382e7099]::ops::function::FnOnce<(), Output = ()> + core[18c8dd30382e7099]::marker::Send> as core[18c8dd30382e7099]::ops::function::FnOnce<()>>::call_once
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/alloc/src/boxed.rs:2249:9
  49:     0x5d286c4b80ff - <std[52919eca6bce4da3]::sys::thread::unix::Thread>::new::thread_start
                               at /rustc/ac68faa20c58cbccd01ee7208bf3b6e93a7d7f96/library/std/src/sys/thread/unix.rs:118:17
  50:     0x7f730069dd53 - start_thread
  51:     0x7f730072563c - __clone3
  52:                0x0 - <unknown>


failures:
    thetest

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

If I double wrap the brackets like this:

    check(expect![[
        "the argument '--from <FROM>' is required because some dependency arguments are provided"
    ]]);

Then self-update works without panicking, but replaces the code back into single-bracket. This means if the expected content changes later, the next self-update will panic again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions