`format_args` can create incorrect subspans for raw string literals that adopted another string literal’s span – `assertion failed: bpos.to_u32() >= mbc.pos.to_u32() + mbc.bytes as u32` #114865
Another fun effect: If the macro-generated string is longer, e.g.
let mut lit: Literal = r#"r" {}""#.parse().unwrap();
then the error message first points in other places in my program, and eventually also into different files:
error: 1 positional argument in format string, but no arguments were given
--> /home/…USER…/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/lib.rs:1:9
|
1 | //! # The Rust Standard Library
| ^^
Playing around with
indoc
, I’ve noticed that while a format string thatindoc
doesn’t modify further, likeleads to an error message that has a span pointing into the string literal
When the string is modified by
indoc
(removing some leading whitespace) likethat leads to an error message spanning the whole string literal.
So far so good, this all looks intentional. However with raw string literals, the behavior is no longer the same:
Without modification
and with modification by
indoc
Now we have a span pointing to the wrong location.
Apparently that’s sufficient to make the compiler crash, if multi-byte characters are involved. E.g.
([run on rustexplorer.com](https://www.rustexplorer.com/b#%2F*%0A%5Bdependencies%5D%0Aindoc%20%3D%20%222%22%0A*%2F%0A%0Afn%20main()%20%7B%0Aindoc%3A%3Aprintdoc!(%0Ar%22%0A%20%F0%9F%87%A9%F0%9F%87%AA%7B%7D%22%0A)%3B%0A%7D%0A))
This is the assertion that fails: https://github.com/rust-lang/rust/blob/c57393e4f8b88444fbf0985a81a2d662862f2733/compiler/rustc_span/src/lib.rs#L1760-L1762
As for a minimal reproduction, define a proc-macro
and then use it like so
Another fun effect: If the macro-generated string is longer, e.g.
then the error message first points in other places in my program, and eventually also into different files:
This reproduces for latest stable and nightly.