> then I can't map that back into the original string (because the parsed text is one character shorter than the source string, but I don't actually know how to map arbitrary spans form the parsed string back to the source string).

It's not one character shorter: the newline is registered in the spans of the parsed text (assuming `parse_expr` isn't mangling its output too much, which is possible too).

Theoretically it would be possible to construct a span covering `foo\n.bar()` (if the `.parse_expr` method were set up correctly (taking a span for its string) this could even be automatic). However, I definitely don't think it's worth trying to hack spans like this.