From 65bb09d434758257750e3d44bffd668e2f4b70c5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 19 Nov 2023 20:12:16 -0800 Subject: [PATCH] Handle $message_type in JSON diagnostics --- crates/cargo-test-support/src/compare.rs | 37 +++++++++++++++++++----- tests/testsuite/doc.rs | 1 + tests/testsuite/metabuild.rs | 1 + 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/crates/cargo-test-support/src/compare.rs b/crates/cargo-test-support/src/compare.rs index d9e8d5454d0..fc1663d344b 100644 --- a/crates/cargo-test-support/src/compare.rs +++ b/crates/cargo-test-support/src/compare.rs @@ -591,15 +591,36 @@ fn find_json_mismatch_r<'a>( .next() } (&Object(ref l), &Object(ref r)) => { - let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k)); - if !same_keys { - return Some((expected, actual)); + let mut expected_entries = l.iter(); + let mut actual_entries = r.iter(); + + // Compilers older than 1.76 do not produce $message_type. + // Treat it as optional for now. + let mut expected_entries_without_message_type; + let expected_entries: &mut dyn Iterator = + if l.contains_key("$message_type") && !r.contains_key("$message_type") { + expected_entries_without_message_type = + expected_entries.filter(|entry| entry.0 != "$message_type"); + &mut expected_entries_without_message_type + } else { + &mut expected_entries + }; + + loop { + match (expected_entries.next(), actual_entries.next()) { + (None, None) => return None, + (Some((expected_key, expected_value)), Some((actual_key, actual_value))) + if expected_key == actual_key => + { + if let mismatch @ Some(_) = + find_json_mismatch_r(expected_value, actual_value, cwd) + { + return mismatch; + } + } + _ => return Some((expected, actual)), + } } - - l.values() - .zip(r.values()) - .filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd)) - .next() } (&Null, &Null) => None, // Magic string literal `"{...}"` acts as wildcard for any sub-JSON. diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 43d5f6c8356..37dd47d76fd 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -1698,6 +1698,7 @@ fn doc_message_format() { r#" { "message": { + "$message_type": "diagnostic", "children": "{...}", "code": "{...}", "level": "error", diff --git a/tests/testsuite/metabuild.rs b/tests/testsuite/metabuild.rs index 022d0bff046..1c0196c987b 100644 --- a/tests/testsuite/metabuild.rs +++ b/tests/testsuite/metabuild.rs @@ -740,6 +740,7 @@ fn metabuild_failed_build_json() { r#" { "message": { + "$message_type": "diagnostic", "children": "{...}", "code": "{...}", "level": "error",