diff --git a/src/lints/union_field_added_with_all_pub_fields.ron b/src/lints/union_field_added_with_all_pub_fields.ron new file mode 100644 index 00000000..fb9ce24f --- /dev/null +++ b/src/lints/union_field_added_with_all_pub_fields.ron @@ -0,0 +1,93 @@ +SemverQuery( + id: "union_field_added_with_all_pub_fields", + human_readable_name: "union with only public API fields added a new field", + description: "A union with only public API fields added a new field, possibly changing the union's bit-compatibility.", + required_update: Major, + lint_level: Deny, + reference_link: Some("https://github.com/obi1kenobi/cargo-semver-checks/issues/950"), + query: r#" + { + CrateDiff { + baseline { + item { + ... on Union { + visibility_limit @filter(op: "=", value: ["$public"]) + + attribute { + content { + base @filter(op: "=", value: ["$repr"]) + argument { + base @filter(op: "=", value: ["$c"]) + } + } + } + + importable_path { + path @output @tag + public_api @filter(op: "=", value: ["$true"]) + } + + # None of the union's fields are non-public-API. + field @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + public_api_eligible @filter(op: "!=", value: ["$true"]) + } + } + } + } + current { + item { + ... on Union { + visibility_limit @filter(op: "=", value: ["$public"]) + union_name: name @output + + attribute { + content { + base @filter(op: "=", value: ["$repr"]) + argument { + base @filter(op: "=", value: ["$c"]) + } + } + } + + importable_path { + path @filter(op: "=", value: ["%path"]) + public_api @filter(op: "=", value: ["$true"]) + } + + field { + field_name: name @output @tag + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + baseline { + item { + ... on Union { + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + # The original union's definition didn't include the field we're looking at. + field @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + name @filter(op: "=", value: ["%field_name"]) + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "true": true, + "zero": 0, + "repr": "repr", + "c": "C", + }, + error_message: "A public repr(C) union with only public fields has added a new field, which may change the union's bit-compatibility rules. This may invalidate downstream safety invariants and cause those programs to become unsound.", + per_result_error_template: Some("field {{union_name}}.{{field_name}} in file {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/lints/union_field_added_with_non_pub_fields.ron b/src/lints/union_field_added_with_non_pub_fields.ron new file mode 100644 index 00000000..ba01b322 --- /dev/null +++ b/src/lints/union_field_added_with_non_pub_fields.ron @@ -0,0 +1,95 @@ +SemverQuery( + id: "union_field_added_with_non_pub_fields", + human_readable_name: "union with some non-public API fields added a new field", + description: "A union with some non-public API fields added a new field, possibly changing the union's bit-compatibility.", + required_update: Major, + lint_level: Warn, + reference_link: Some("https://github.com/obi1kenobi/cargo-semver-checks/issues/950"), + query: r#" + { + CrateDiff { + baseline { + item { + ... on Union { + visibility_limit @filter(op: "=", value: ["$public"]) + + attribute { + content { + base @filter(op: "=", value: ["$repr"]) + argument { + base @filter(op: "=", value: ["$c"]) + } + } + } + + importable_path { + path @output @tag + public_api @filter(op: "=", value: ["$true"]) + } + + # Some of the union's fields are non-public-API. + # The case where all the union's fields are public API is handled + # in the `union_field_added_with_all_pub_fields` lint. + field @fold @transform(op: "count") @filter(op: ">", value: ["$zero"]) { + public_api_eligible @filter(op: "!=", value: ["$true"]) + } + } + } + } + current { + item { + ... on Union { + visibility_limit @filter(op: "=", value: ["$public"]) + union_name: name @output + + attribute { + content { + base @filter(op: "=", value: ["$repr"]) + argument { + base @filter(op: "=", value: ["$c"]) + } + } + } + + importable_path { + path @filter(op: "=", value: ["%path"]) + public_api @filter(op: "=", value: ["$true"]) + } + + field { + field_name: name @output @tag + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + baseline { + item { + ... on Union { + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + # The original union's definition didn't include the field we're looking at. + field @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + name @filter(op: "=", value: ["%field_name"]) + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "true": true, + "zero": 0, + "repr": "repr", + "c": "C", + }, + error_message: "A public repr(C) union with some non-public fields has added a new field, which may change the union's bit-compatibility rules. While the non-public fields didn't promise any specific bit-compatibility, Hyrum's Law says that downstream users may still have been relying on bit-compatibility assumptions that may now be broken. This may invalidate those users' safety invariants and cause those programs to become unsound.", + per_result_error_template: Some("field {{union_name}}.{{field_name}} in file {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/lints/union_pub_field_now_doc_hidden.ron b/src/lints/union_pub_field_now_doc_hidden.ron index b38d796d..66f7b14f 100644 --- a/src/lints/union_pub_field_now_doc_hidden.ron +++ b/src/lints/union_pub_field_now_doc_hidden.ron @@ -46,7 +46,12 @@ SemverQuery( field { name @filter(op: "=", value: ["%field_name"]) + + # We have to ensure that the field is non-public-API + # *by reason of* becoming `#[doc(hidden)]`. Otherwise, + # this lint will trigger on fields becoming non-`pub` as well. public_api_eligible @filter(op: "!=", value: ["$true"]) + doc_hidden @filter(op: "=", value: ["$true"]) } span_: span @optional { diff --git a/src/query.rs b/src/query.rs index d9466e3e..334be58d 100644 --- a/src/query.rs +++ b/src/query.rs @@ -1218,6 +1218,8 @@ add_lints!( tuple_struct_to_plain_struct, type_marked_deprecated, type_mismatched_generic_lifetimes, + union_field_added_with_all_pub_fields, + union_field_added_with_non_pub_fields, union_field_missing, union_missing, union_must_use_added, diff --git a/test_crates/union_field_added/new/Cargo.toml b/test_crates/union_field_added/new/Cargo.toml new file mode 100644 index 00000000..bd6c88da --- /dev/null +++ b/test_crates/union_field_added/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "union_field_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/union_field_added/new/src/lib.rs b/test_crates/union_field_added/new/src/lib.rs new file mode 100644 index 00000000..4b6ede52 --- /dev/null +++ b/test_crates/union_field_added/new/src/lib.rs @@ -0,0 +1,90 @@ +// Should trigger `union_field_added_with_all_pub_fields`. +#[repr(C)] +pub union AllPubFields { + pub a: [i32; 2], + pub b: i64, + pub c: *const i64, +} + +// Should trigger `union_field_added_with_non_pub_fields`. +#[repr(C)] +pub union SomeHiddenPubFields { + pub a: [i32; 2], + + #[doc(hidden)] + pub b: i64, + + #[doc(hidden)] + pub c: *const i64, +} + +// Should trigger `union_field_added_with_non_pub_fields`. +#[repr(C)] +pub union SomePrivateFields { + pub a: [i32; 2], + pub(crate) b: i64, + c: *const i64, +} + +// Shouldn't trigger the "union field added" lints, +// but will trigger the "repr(C) removed" lint for unions. +pub union ReprCRemovedAllPublicFields { + pub a: [i32; 2], + pub b: i64, + pub c: *const i64, +} + +// Shouldn't trigger the "union field added" lints, +// but will trigger the "repr(C) removed" lint for unions. +pub union ReprCRemovedNonPublicFields { + pub a: [i32; 2], + b: i64, + c: *const i64, +} + +// Shouldn't trigger any of the lints. +#[repr(C)] +pub union BecameReprC { + pub a: [i32; 2], + pub b: i64, + pub c: *const i64, +} + +// Should trigger `union_field_added_with_all_pub_fields` +// even though a field also became non-public-API. +#[repr(C)] +pub union FieldBecameNonPublic { + pub a: [i32; 2], + b: i64, + c: *const i64, +} + +// Should trigger `union_field_added_with_all_pub_fields` +// even though a field also became non-public-API. +#[repr(C)] +pub union FieldBecameNonPublicAPI { + pub a: [i32; 2], + + #[doc(hidden)] + pub b: i64, + + pub c: *const i64, +} + +// Should trigger `union_field_added_with_non_pub_fields` +// even though the non-public-API field also became public API. +#[repr(C)] +pub union HiddenFieldBecamePublicAPI { + pub a: [i32; 2], + pub b: i64, + pub c: *const i64, +} + +// Should trigger `union_field_added_with_non_pub_fields` +// even though the non-public field also became public API. +#[repr(C)] +pub union PrivateFieldBecamePublicAPI { + pub a: [i32; 2], + pub b: i64, + pub c: *const i64, +} diff --git a/test_crates/union_field_added/old/Cargo.toml b/test_crates/union_field_added/old/Cargo.toml new file mode 100644 index 00000000..bd6c88da --- /dev/null +++ b/test_crates/union_field_added/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "union_field_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/union_field_added/old/src/lib.rs b/test_crates/union_field_added/old/src/lib.rs new file mode 100644 index 00000000..3092f447 --- /dev/null +++ b/test_crates/union_field_added/old/src/lib.rs @@ -0,0 +1,79 @@ +// Should trigger `union_field_added_with_all_pub_fields`. +#[repr(C)] +pub union AllPubFields { + pub a: [i32; 2], + pub b: i64, +} + +// Should trigger `union_field_added_with_non_pub_fields`. +#[repr(C)] +pub union SomeHiddenPubFields { + pub a: [i32; 2], + + #[doc(hidden)] + pub b: i64, +} + +// Should trigger `union_field_added_with_non_pub_fields`. +#[repr(C)] +pub union SomePrivateFields { + pub a: [i32; 2], + pub(crate) b: i64, +} + +// Shouldn't trigger the "union field added" lints, +// but will trigger the "repr(C) removed" lint for unions. +#[repr(C)] +pub union ReprCRemovedAllPublicFields { + pub a: [i32; 2], + pub b: i64, +} + +// Shouldn't trigger the "union field added" lints, +// but will trigger the "repr(C) removed" lint for unions. +#[repr(C)] +pub union ReprCRemovedNonPublicFields { + pub a: [i32; 2], + b: i64, +} + +// Shouldn't trigger any of the lints. +pub union BecameReprC { + pub a: [i32; 2], + pub b: i64, +} + + +// Should trigger `union_field_added_with_all_pub_fields` +// even though a field also became non-public-API. +#[repr(C)] +pub union FieldBecameNonPublic { + pub a: [i32; 2], + pub b: i64, +} + +// Should trigger `union_field_added_with_all_pub_fields` +// even though a field also became non-public-API. +#[repr(C)] +pub union FieldBecameNonPublicAPI { + pub a: [i32; 2], + pub b: i64, +} + +// Should trigger `union_field_added_with_non_pub_fields` +// even though the non-public-API field also became public API. +#[repr(C)] +pub union HiddenFieldBecamePublicAPI { + pub a: [i32; 2], + + #[doc(hidden)] + pub b: i64, +} + +// Should trigger `union_field_added_with_non_pub_fields` +// even though the non-public field also became public API. +#[repr(C)] +pub union PrivateFieldBecamePublicAPI { + pub a: [i32; 2], + b: i64, +} diff --git a/test_outputs/query_execution/auto_trait_impl_removed.snap b/test_outputs/query_execution/auto_trait_impl_removed.snap index b1f1a59e..4be4eaa2 100644 --- a/test_outputs/query_execution/auto_trait_impl_removed.snap +++ b/test_outputs/query_execution/auto_trait_impl_removed.snap @@ -1,6 +1,7 @@ --- source: src/query.rs expression: "&query_execution_results" +snapshot_kind: text --- { "./test_crates/auto_trait_impl_removed/": [ @@ -87,4 +88,326 @@ expression: "&query_execution_results" "visibility_limit": String("public"), }, ], + "./test_crates/union_field_added/": [ + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("AllPubFields"), + "path": List([ + String("union_field_added"), + String("AllPubFields"), + ]), + "span_begin_line": Uint64(3), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("AllPubFields"), + "path": List([ + String("union_field_added"), + String("AllPubFields"), + ]), + "span_begin_line": Uint64(3), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("SomeHiddenPubFields"), + "path": List([ + String("union_field_added"), + String("SomeHiddenPubFields"), + ]), + "span_begin_line": Uint64(11), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("SomeHiddenPubFields"), + "path": List([ + String("union_field_added"), + String("SomeHiddenPubFields"), + ]), + "span_begin_line": Uint64(11), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("SomePrivateFields"), + "path": List([ + String("union_field_added"), + String("SomePrivateFields"), + ]), + "span_begin_line": Uint64(23), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("SomePrivateFields"), + "path": List([ + String("union_field_added"), + String("SomePrivateFields"), + ]), + "span_begin_line": Uint64(23), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("ReprCRemovedAllPublicFields"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedAllPublicFields"), + ]), + "span_begin_line": Uint64(31), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("ReprCRemovedAllPublicFields"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedAllPublicFields"), + ]), + "span_begin_line": Uint64(31), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("ReprCRemovedNonPublicFields"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedNonPublicFields"), + ]), + "span_begin_line": Uint64(39), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("ReprCRemovedNonPublicFields"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedNonPublicFields"), + ]), + "span_begin_line": Uint64(39), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("BecameReprC"), + "path": List([ + String("union_field_added"), + String("BecameReprC"), + ]), + "span_begin_line": Uint64(47), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("BecameReprC"), + "path": List([ + String("union_field_added"), + String("BecameReprC"), + ]), + "span_begin_line": Uint64(47), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("FieldBecameNonPublic"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublic"), + ]), + "span_begin_line": Uint64(56), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("FieldBecameNonPublic"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublic"), + ]), + "span_begin_line": Uint64(56), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("FieldBecameNonPublicAPI"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublicAPI"), + ]), + "span_begin_line": Uint64(65), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("FieldBecameNonPublicAPI"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublicAPI"), + ]), + "span_begin_line": Uint64(65), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("HiddenFieldBecamePublicAPI"), + "path": List([ + String("union_field_added"), + String("HiddenFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(77), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("HiddenFieldBecamePublicAPI"), + "path": List([ + String("union_field_added"), + String("HiddenFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(77), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Send"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Send"), + ]), + "name": String("PrivateFieldBecamePublicAPI"), + "path": List([ + String("union_field_added"), + String("PrivateFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(86), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "auto_trait": String("Sync"), + "auto_trait_path": List([ + String("core"), + String("marker"), + String("Sync"), + ]), + "name": String("PrivateFieldBecamePublicAPI"), + "path": List([ + String("union_field_added"), + String("PrivateFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(86), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], } diff --git a/test_outputs/query_execution/repr_c_removed.snap b/test_outputs/query_execution/repr_c_removed.snap index 2ffd4cc2..508847a0 100644 --- a/test_outputs/query_execution/repr_c_removed.snap +++ b/test_outputs/query_execution/repr_c_removed.snap @@ -1,6 +1,7 @@ --- source: src/query.rs expression: "&query_execution_results" +snapshot_kind: text --- { "./test_crates/repr_c_removed/": [ @@ -161,4 +162,30 @@ expression: "&query_execution_results" "visibility_limit": String("public"), }, ], + "./test_crates/union_field_added/": [ + { + "name": String("ReprCRemovedAllPublicFields"), + "old_attr": String("#[repr(C)]"), + "owner_type": String("Union"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedAllPublicFields"), + ]), + "span_begin_line": Uint64(31), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("ReprCRemovedNonPublicFields"), + "old_attr": String("#[repr(C)]"), + "owner_type": String("Union"), + "path": List([ + String("union_field_added"), + String("ReprCRemovedNonPublicFields"), + ]), + "span_begin_line": Uint64(39), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], } diff --git a/test_outputs/query_execution/union_field_added_with_all_pub_fields.snap b/test_outputs/query_execution/union_field_added_with_all_pub_fields.snap new file mode 100644 index 00000000..b476612b --- /dev/null +++ b/test_outputs/query_execution/union_field_added_with_all_pub_fields.snap @@ -0,0 +1,39 @@ +--- +source: src/query.rs +expression: "&query_execution_results" +snapshot_kind: text +--- +{ + "./test_crates/union_field_added/": [ + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("AllPubFields"), + ]), + "span_begin_line": Uint64(6), + "span_filename": String("src/lib.rs"), + "union_name": String("AllPubFields"), + }, + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublic"), + ]), + "span_begin_line": Uint64(59), + "span_filename": String("src/lib.rs"), + "union_name": String("FieldBecameNonPublic"), + }, + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublicAPI"), + ]), + "span_begin_line": Uint64(71), + "span_filename": String("src/lib.rs"), + "union_name": String("FieldBecameNonPublicAPI"), + }, + ], +} diff --git a/test_outputs/query_execution/union_field_added_with_non_pub_fields.snap b/test_outputs/query_execution/union_field_added_with_non_pub_fields.snap new file mode 100644 index 00000000..2321bbc2 --- /dev/null +++ b/test_outputs/query_execution/union_field_added_with_non_pub_fields.snap @@ -0,0 +1,49 @@ +--- +source: src/query.rs +expression: "&query_execution_results" +snapshot_kind: text +--- +{ + "./test_crates/union_field_added/": [ + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("SomeHiddenPubFields"), + ]), + "span_begin_line": Uint64(18), + "span_filename": String("src/lib.rs"), + "union_name": String("SomeHiddenPubFields"), + }, + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("SomePrivateFields"), + ]), + "span_begin_line": Uint64(26), + "span_filename": String("src/lib.rs"), + "union_name": String("SomePrivateFields"), + }, + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("HiddenFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(80), + "span_filename": String("src/lib.rs"), + "union_name": String("HiddenFieldBecamePublicAPI"), + }, + { + "field_name": String("c"), + "path": List([ + String("union_field_added"), + String("PrivateFieldBecamePublicAPI"), + ]), + "span_begin_line": Uint64(89), + "span_filename": String("src/lib.rs"), + "union_name": String("PrivateFieldBecamePublicAPI"), + }, + ], +} diff --git a/test_outputs/query_execution/union_field_missing.snap b/test_outputs/query_execution/union_field_missing.snap index 74207c85..705fe13c 100644 --- a/test_outputs/query_execution/union_field_missing.snap +++ b/test_outputs/query_execution/union_field_missing.snap @@ -1,8 +1,21 @@ --- source: src/query.rs expression: "&query_execution_results" +snapshot_kind: text --- { + "./test_crates/union_field_added/": [ + { + "field_name": String("b"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublic"), + ]), + "span_begin_line": Uint64(52), + "span_filename": String("src/lib.rs"), + "union_name": String("FieldBecameNonPublic"), + }, + ], "./test_crates/union_field_missing/": [ { "field_name": String("f2"), diff --git a/test_outputs/query_execution/union_pub_field_now_doc_hidden.snap b/test_outputs/query_execution/union_pub_field_now_doc_hidden.snap index fec06005..483d7b6d 100644 --- a/test_outputs/query_execution/union_pub_field_now_doc_hidden.snap +++ b/test_outputs/query_execution/union_pub_field_now_doc_hidden.snap @@ -1,8 +1,21 @@ --- source: src/query.rs expression: "&query_execution_results" +snapshot_kind: text --- { + "./test_crates/union_field_added/": [ + { + "field_name": String("b"), + "path": List([ + String("union_field_added"), + String("FieldBecameNonPublicAPI"), + ]), + "span_begin_line": Uint64(65), + "span_filename": String("src/lib.rs"), + "union_name": String("FieldBecameNonPublicAPI"), + }, + ], "./test_crates/union_now_doc_hidden/": [ { "field_name": String("my_field"),