Move format args decompiler and support infra to separate mods#429
Move format args decompiler and support infra to separate mods#429Firestar99 merged 5 commits intomainfrom
Conversation
| // HACK(eddyb) Rust 2021 `panic!` always uses `format_args!`, even | ||
| // in the simple case that used to pass a `&str` constant, which | ||
| // would not remain reachable in the SPIR-V - but `format_args!` is | ||
| // more complex and neither immediate (`fmt::Arguments` is too big) | ||
| // nor simplified in MIR (e.g. promoted to a constant) in any way, | ||
| // so we have to try and remove the `fmt::Arguments::new` call here. | ||
| #[derive(Default)] | ||
| struct DecodedFormatArgs<'tcx> { | ||
| /// If fully constant, the `pieces: &'a [&'static str]` input | ||
| /// of `fmt::Arguments<'a>` (i.e. the strings between args). | ||
| const_pieces: Option<SmallVec<[String; 2]>>, | ||
|
|
||
| /// Original references for `fmt::Arguments<'a>` dynamic arguments, | ||
| /// i.e. the `&'a T` passed to `fmt::rt::Argument::<'a>::new_*`, | ||
| /// tracking the type `T` and `char` formatting specifier. | ||
| /// | ||
| /// E.g. for `format_args!("{a} {b:x}")` they'll be: | ||
| /// * `&a` with `typeof a` and ' ', | ||
| /// * `&b` with `typeof b` and 'x' | ||
| ref_arg_ids_with_ty_and_spec: SmallVec<[(Word, Ty<'tcx>, char); 2]>, | ||
|
|
||
| /// If `fmt::Arguments::new_v1_formatted` was used, this holds | ||
| /// the length of the `&[fmt::rt::Placeholder]` slice, which | ||
| /// currently cannot be directly supported, and therefore even | ||
| /// if all of `ref_arg_ids_with_ty_and_spec` are printable, | ||
| /// a much jankier fallback still has to be used, as it it were: | ||
| /// | ||
| /// `format!("a{{0}}b{{1}}c\n with {{…}} from: {}, {}", x, y)` | ||
| /// (w/ `const_pieces = ["a", "b", "c"]` & `ref_args = [&x, &y]`). | ||
| has_unknown_fmt_placeholder_to_args_mapping: Option<usize>, | ||
| } | ||
| struct FormatArgsNotRecognized(String); | ||
|
|
||
| // HACK(eddyb) this is basically a `try` block. | ||
| let mut try_decode_and_remove_format_args = || { |
There was a problem hiding this comment.
I think it would make more sense to make these types (and the closure becoming a method) the real interface here, and name the module format_args_decompiler (because that's what this cursedness really is).
In theory we could allow non-panic uses of it, like instead of debug_printf! we could have debug_print! (or even the Rust std dbg! macro), that uses format_args! combined with a function that we treat just like we do panic entry-points.
There was a problem hiding this comment.
done, feel free to rereview. Not a huge fan how I handled the Result, but wrapping it in a new type makes the function super ugly.
fa07e53 to
e434f66
Compare
e434f66 to
177162b
Compare
|
Added a few more things:
|
177162b to
7db75b6
Compare
|
Wouldn't be surprised if the merge failed on a conflict in |
… debug_printf` Currently, every time `lib.rs` changes, there's a change in the debug printf compiletest stderr, which is causing a lot of churn.
7db75b6 to
5a623d2
Compare
@eddyb mind if we move that code to declutter
call?