cargo-semver-checks 0.40.0

Scan your Rust crate for semver violations.
Documentation
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
                                end_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}}"),
)