From c72296ea00a2dfc849f2e6670d691a0af111faf2 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 06:40:55 +0000 Subject: [PATCH 1/4] ruff_charon: Kythe output golden for cg_lib/cg_app rev1, before rows v2 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01X6y3drwKSE2zSgoexheLFX --- .../tests/data/cg_app.kythe.golden | 27 ++++++ .../tests/data/cg_lib.kythe.golden | 83 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 crates/ruff_charon/tests/data/cg_app.kythe.golden create mode 100644 crates/ruff_charon/tests/data/cg_lib.kythe.golden diff --git a/crates/ruff_charon/tests/data/cg_app.kythe.golden b/crates/ruff_charon/tests/data/cg_app.kythe.golden new file mode 100644 index 0000000000000..59ff3b231fe47 --- /dev/null +++ b/crates/ruff_charon/tests/data/cg_app.kythe.golden @@ -0,0 +1,27 @@ +{"fact_name":"/kythe/node/kind","fact_value":"ZmlsZQ==","source":{"corpus":"lance-graph","language":"","path":"cg_app/src/lib.rs","root":"","signature":""}} +{"fact_name":"/kythe/text","fact_value":"dXNlIGNnX2xpYjo6c2hhcGVzOjp7UmVjdCwgU2hhcGV9Owp1c2UgY2dfbGliOjpTcTsKCnB1YiBmbiBydW4oKSAtPiB1MzIgewogICAgbGV0IHMgPSBTcSgzKTsKICAgIGxldCByID0gUmVjdCgxLCAyKTsKICAgIGNnX2xpYjo6YXJlYV9vZigmcykgKyBjZ19saWI6OmFyZWFfZHluKCZyKSArIHMuYXJlYSgpICsgY2dfbGliOjp1dGlsOjpkb3VibGUoMikKfQo=","source":{"corpus":"lance-graph","language":"","path":"cg_app/src/lib.rs","root":"","signature":""}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@52:202"}} +{"fact_name":"/kythe/loc/start","fact_value":"NTI=","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@52:202"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjAy","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@52:202"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@52:202"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@121:140"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTIx","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@121:140"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTQw","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@121:140"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@121:140"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_of"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@121:140"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@143:163"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTQz","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@143:163"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTYz","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@143:163"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@143:163"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_dyn"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@143:163"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@166:174"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTY2","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@166:174"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTc0","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@166:174"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@166:174"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Square::area"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@166:174"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@177:200"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTc3","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@177:200"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjAw","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@177:200"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@177:200"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::double"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_app/src/lib.rs","root":"","signature":"@177:200"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_app::run"}} diff --git a/crates/ruff_charon/tests/data/cg_lib.kythe.golden b/crates/ruff_charon/tests/data/cg_lib.kythe.golden new file mode 100644 index 0000000000000..b0ad07ac79356 --- /dev/null +++ b/crates/ruff_charon/tests/data/cg_lib.kythe.golden @@ -0,0 +1,83 @@ +{"fact_name":"/kythe/node/kind","fact_value":"ZmlsZQ==","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/lib.rs","root":"","signature":""}} +{"fact_name":"/kythe/text","fact_value":"cHViIG1vZCBtYWNyb191c2U7CnB1YiBtb2Qgc2hhcGVzOwpwdWIgbW9kIHV0aWw7CgpwdWIgdXNlIHNoYXBlczo6U3F1YXJlIGFzIFNxOwoKcHViIGZuIGFyZWFfb2Y8Uzogc2hhcGVzOjpTaGFwZT4oczogJlMpIC0+IHUzMiB7CiAgICBzLmFyZWEoKQp9CgpwdWIgZm4gYXJlYV9keW4oczogJmR5biBzaGFwZXM6OlNoYXBlKSAtPiB1MzIgewogICAgcy5hcmVhKCkKfQoKI1tjZmcoYW55KCkpXQpwdWIgZm4gZGlzYWJsZWQoKSAtPiB1MzIgewogICAgdXRpbDo6ZG91YmxlKDEpCn0K","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/lib.rs","root":"","signature":""}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@81:144"}} +{"fact_name":"/kythe/loc/start","fact_value":"ODE=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@81:144"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTQ0","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@81:144"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_of"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@81:144"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_of"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@134:142"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTM0","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@134:142"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTQy","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@134:142"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@134:142"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::Shape"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@134:142"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_of"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@146:208"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTQ2","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@146:208"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjA4","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@146:208"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_dyn"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@146:208"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::area_dyn"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@198:206"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTk4","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@198:206"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjA2","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/lib.rs","root":"","signature":"@198:206"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZmlsZQ==","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/macro_use.rs","root":"","signature":""}} +{"fact_name":"/kythe/text","fact_value":"dXNlIGNyYXRlOjp1dGlsOjp0cmlwbGUgYXMgdDM7CgpwdWIgZm4gY2hlY2tlZCgpIC0+IHUzMiB7CiAgICBhc3NlcnRfZXEhKHQzKDEpLCAzKTsKICAgIDEKfQo=","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/macro_use.rs","root":"","signature":""}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@32:91"}} +{"fact_name":"/kythe/loc/start","fact_value":"MzI=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@32:91"}} +{"fact_name":"/kythe/loc/end","fact_value":"OTE=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@32:91"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@32:91"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@73:78"}} +{"fact_name":"/kythe/loc/start","fact_value":"NzM=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@73:78"}} +{"fact_name":"/kythe/loc/end","fact_value":"Nzg=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@73:78"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@73:78"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::triple"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@73:78"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"}} +{"fact_name":"/kythe/loc/start","fact_value":"NjI=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"}} +{"fact_name":"/kythe/loc/end","fact_value":"ODI=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"core::panicking::assert_failed"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZmlsZQ==","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/util.rs","root":"","signature":""}} +{"fact_name":"/kythe/text","fact_value":"dXNlIGNyYXRlOjpzaGFwZXM6OlNxdWFyZTsKCnB1YiBmbiBkb3VibGUoeDogdTMyKSAtPiB1MzIgewogICAgeCAqIDIKfQoKcHViIGZuIHRyaXBsZSh4OiB1MzIpIC0+IHUzMiB7CiAgICB4ICogMwp9CgpwdWIgZm4gdW5pdCgpIC0+IFNxdWFyZSB7CiAgICBTcXVhcmUoMSkKfQoKZm4gcHJpdmF0ZV91bnVzZWQoKSAtPiB1MzIgewogICAgMAp9Cg==","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/util.rs","root":"","signature":""}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@28:70"}} +{"fact_name":"/kythe/loc/start","fact_value":"Mjg=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@28:70"}} +{"fact_name":"/kythe/loc/end","fact_value":"NzA=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@28:70"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::double"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@28:70"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::double"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@72:114"}} +{"fact_name":"/kythe/loc/start","fact_value":"NzI=","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@72:114"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTE0","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@72:114"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::triple"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@72:114"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::triple"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@116:157"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTE2","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@116:157"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTU3","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@116:157"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::unit"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@116:157"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::unit"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@159:195"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTU5","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@159:195"}} +{"fact_name":"/kythe/loc/end","fact_value":"MTk1","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@159:195"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::private_unused"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/util.rs","root":"","signature":"@159:195"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::private_unused"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZmlsZQ==","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/shapes.rs","root":"","signature":""}} +{"fact_name":"/kythe/text","fact_value":"dXNlIGNyYXRlOjp1dGlsOjpkb3VibGU7CnVzZSBjcmF0ZTo6dXRpbDo6dHJpcGxlOwoKcHViIHRyYWl0IFNoYXBlIHsKICAgIGZuIGFyZWEoJnNlbGYpIC0+IHUzMjsKfQoKcHViIHN0cnVjdCBTcXVhcmUocHViIHUzMik7CgpwdWIgc3RydWN0IFJlY3QocHViIHUzMiwgcHViIHUzMik7CgppbXBsIFNoYXBlIGZvciBTcXVhcmUgewogICAgZm4gYXJlYSgmc2VsZikgLT4gdTMyIHsKICAgICAgICBkb3VibGUoc2VsZi4wKSAvIDIgKiBzZWxmLjAKICAgIH0KfQoKaW1wbCBTaGFwZSBmb3IgUmVjdCB7CiAgICBmbiBhcmVhKCZzZWxmKSAtPiB1MzIgewogICAgICAgIHNlbGYuMCAqIHNlbGYuMQogICAgfQp9CgppbXBsIFNxdWFyZSB7CiAgICBwdWIgZm4gc2lkZSgmc2VsZikgLT4gdTMyIHsKICAgICAgICBzZWxmLjAKICAgIH0KfQo=","source":{"corpus":"lance-graph","language":"","path":"cg_lib/src/shapes.rs","root":"","signature":""}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@192:257"}} +{"fact_name":"/kythe/loc/start","fact_value":"MTky","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@192:257"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjU3","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@192:257"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Square::area"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@192:257"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Square::area"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@224:238"}} +{"fact_name":"/kythe/loc/start","fact_value":"MjI0","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@224:238"}} +{"fact_name":"/kythe/loc/end","fact_value":"MjM4","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@224:238"}} +{"edge_kind":"/kythe/edge/ref/call","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@224:238"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::util::double"}} +{"edge_kind":"/kythe/edge/childof","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@224:238"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Square::area"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@287:340"}} +{"fact_name":"/kythe/loc/start","fact_value":"Mjg3","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@287:340"}} +{"fact_name":"/kythe/loc/end","fact_value":"MzQw","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@287:340"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Rect::area"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@287:340"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::impl_Shape_for_Rect::area"}} +{"fact_name":"/kythe/node/kind","fact_value":"YW5jaG9y","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@362:410"}} +{"fact_name":"/kythe/loc/start","fact_value":"MzYy","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@362:410"}} +{"fact_name":"/kythe/loc/end","fact_value":"NDEw","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@362:410"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::{Square}::side"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/shapes.rs","root":"","signature":"@362:410"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::shapes::{Square}::side"}} +{"fact_name":"/kythe/node/kind","fact_value":"ZnVuY3Rpb24=","source":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked::{promoted_const}"}} +{"edge_kind":"/kythe/edge/defines","fact_name":"/","source":{"corpus":"lance-graph","language":"rust","path":"cg_lib/src/macro_use.rs","root":"","signature":"@62:82"},"target":{"corpus":"lance-graph","language":"rust","path":"","root":"","signature":"cg_lib::macro_use::checked::{promoted_const}"}} From 4b5bd15551094e5f8d60b5bba840c6b78381bf42 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 06:44:42 +0000 Subject: [PATCH 2/4] ruff_charon: rows v2 - PUBLIC, IMPLEMENTS, SYNTHETIC, REFERENCES, CRATE status; MAY_DISPATCH names the method Slice C (D-CODEGRAPH-0) needs facts today's rows lack: visibility, which impl method implements which trait method, synthetic items, function-pointer uses (otherwise a pointer-only function reads as dead), and whether Charon reported errors for the crate. MAY_DISPATCH now names Trait::method; Kythe output is unchanged (golden test). Rows artifact version 2. New fixture fnref. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01X6y3drwKSE2zSgoexheLFX --- crates/ruff_charon/src/lib.rs | 181 +++++++++++++++++++++-- crates/ruff_charon/src/store.rs | 10 +- crates/ruff_charon/tests/data/fnref.llbc | 1 + crates/ruff_charon/tests/data/fnref.rs | 14 ++ crates/ruff_charon/tests/intake.rs | 7 +- crates/ruff_charon/tests/intake_v2.rs | 149 +++++++++++++++++++ crates/ruff_charon/tests/store.rs | 2 +- 7 files changed, 346 insertions(+), 18 deletions(-) create mode 100644 crates/ruff_charon/tests/data/fnref.llbc create mode 100644 crates/ruff_charon/tests/data/fnref.rs create mode 100644 crates/ruff_charon/tests/intake_v2.rs diff --git a/crates/ruff_charon/src/lib.rs b/crates/ruff_charon/src/lib.rs index 1cc891b6de916..31ad4ef0de7c9 100644 --- a/crates/ruff_charon/src/lib.rs +++ b/crates/ruff_charon/src/lib.rs @@ -102,6 +102,8 @@ pub enum Callee { Trait { kind: String, trait_id: Option, + /// The trait method the call names. + method: TraitMethodId, impl_fun: Option, }, /// `FnOperand::Dynamic`. @@ -123,6 +125,14 @@ pub struct CallSite { pub site: Option, } +/// A function item or pointer used as a value (not called), in a structured body. +#[derive(Debug, Clone)] +pub struct FnRef { + /// `None` when the reference is not a plain function id (a trait method). + pub target: Option, + pub site: Option, +} + /// What one function's body witnesses. #[derive(Debug, Clone)] pub struct FunFacts { @@ -132,6 +142,8 @@ pub struct FunFacts { pub site: Option, /// `None`: the body is not structured LLBC (opaque, extern, unstructured). pub calls: Option>, + /// Function items and pointers named as values; empty without a structured body. + pub refs: Vec, /// Writes through a dereference rooted in an argument (caller memory; for /// a closure, its captured state is argument 1). pub deref_write_arg: usize, @@ -178,6 +190,24 @@ fn has_deref(place: &Place) -> bool { } } +fn operand_fn_ptr(op: &Operand) -> Option<&FnPtr> { + let Operand::Const(c) = op else { return None }; + match c.kind() { + ConstantExprKind::FnDef(p) | ConstantExprKind::FnPtr(p) => Some(p), + _ => None, + } +} + +/// The operand positions of an rvalue that can hold a function value. +fn rvalue_operands(rv: &Rvalue) -> Vec<&Operand> { + match rv { + Rvalue::Use(op, _) | Rvalue::UnaryOp(_, op) => vec![op], + Rvalue::BinaryOp(_, a, b) => vec![a, b], + Rvalue::Aggregate(_, ops) => ops.iter().collect(), + _ => Vec::new(), + } +} + fn callee(krate: &TranslatedCrate, call: &Call) -> Callee { match &call.func { FnOperand::Regular(ptr) => match ptr.kind.as_ref() { @@ -202,6 +232,7 @@ fn callee(krate: &TranslatedCrate, call: &Call) -> Callee { Callee::Trait { kind: variant(format!("{:?}", tr.kind)), trait_id: Some(tr.trait_decl_ref.id), + method: *method, impl_fun, } } @@ -226,6 +257,7 @@ pub fn fun_facts(krate: &TranslatedCrate, crate_name: &str) -> Vec { name, site: site(krate, f.item_meta.span), calls: None, + refs: Vec::new(), deref_write_arg: 0, deref_write_local: 0, asserts: 0, @@ -233,17 +265,39 @@ pub fn fun_facts(krate: &TranslatedCrate, crate_name: &str) -> Vec { if let Body::Structured(body) = &f.body { let args = body.locals.arg_count; let mut calls = Vec::new(); - body.body.dyn_visit(|st: &Statement| match &st.kind { - StatementKind::Call { call, .. } => calls.push(CallSite { - callee: callee(krate, call), - site: site(krate, st.span), - }), - StatementKind::Assert { .. } => facts.asserts += 1, - StatementKind::Assign(place, _) if has_deref(place) => match root_local(place) { - Some(l) if l.index() <= args => facts.deref_write_arg += 1, - _ => facts.deref_write_local += 1, - }, - _ => {} + body.body.dyn_visit(|st: &Statement| { + // Operands that are function values, never the callee itself + // (`FnOperand` is not an `Operand`). + let operands: Vec<&Operand> = match &st.kind { + StatementKind::Assign(_, rv) => rvalue_operands(rv), + StatementKind::Call { call, .. } => call.args.iter().collect(), + _ => Vec::new(), + }; + for op in operands { + if let Some(ptr) = operand_fn_ptr(op) { + facts.refs.push(FnRef { + target: match ptr.kind.as_ref() { + FnPtrKind::Fun(id) => Some(*id), + FnPtrKind::Trait(..) => None, + }, + site: site(krate, st.span), + }); + } + } + match &st.kind { + StatementKind::Call { call, .. } => calls.push(CallSite { + callee: callee(krate, call), + site: site(krate, st.span), + }), + StatementKind::Assert { .. } => facts.asserts += 1, + StatementKind::Assign(place, _) if has_deref(place) => { + match root_local(place) { + Some(l) if l.index() <= args => facts.deref_write_arg += 1, + _ => facts.deref_write_local += 1, + } + } + _ => {} + } }); facts.calls = Some(calls); } @@ -302,6 +356,9 @@ pub struct Relation { pub subject: String, pub object: String, pub site: Option, + /// What a Kythe `ref/call` points at when it is not `object`: the plain + /// trait name for `MAY_DISPATCH`, which Kythe reads as the declaration. + pub kythe_target: Option, } /// Something Charon gave that no relation represents, with the reason. @@ -342,7 +399,63 @@ pub fn relations( subject: f.qualified.clone(), object: f.qualified.clone(), site: f.site.clone(), + kythe_target: None, }); + let decl = krate.fun_decls.get(f.id); + let mut marker = |predicate: &'static str, object: String| { + receipt.harvested += 1; + rows.push(Relation { + predicate, + subject: f.qualified.clone(), + object, + site: f.site.clone(), + kythe_target: None, + }); + }; + if let Some(d) = decl { + if d.item_meta.attr_info.public { + marker("PUBLIC", f.qualified.clone()); + } + if d.item_meta + .name + .name + .iter() + .any(|e| !matches!(e, PathElem::Ident(..) | PathElem::Impl(_))) + { + marker("SYNTHETIC", f.qualified.clone()); + } + } + if let Some(d) = decl + && let FunSource::TraitImpl { + trait_ref, item_id, .. + } + | FunSource::TraitDefault { + trait_ref, item_id, .. + } = &d.src + { + let named = krate.trait_decls.get(trait_ref.id).and_then(|t| { + let m = t.methods.get(*item_id)?; + Some(format!( + "{}::{}", + qualified_name(krate, &t.item_meta.name), + m.skip_binder.name + )) + }); + receipt.harvested += 1; + match named { + Some(object) => rows.push(Relation { + predicate: "IMPLEMENTS", + subject: f.qualified.clone(), + object, + site: f.site.clone(), + kythe_target: None, + }), + None => residual.push(Residual { + reason: "TRAIT_METHOD_NOT_FOUND", + subject: f.qualified.clone(), + }), + } + } let Some(calls) = f.calls else { // The body is an item of its own: harvested here, represented by // nothing, so it is the residual. The definition above stays @@ -356,6 +469,7 @@ pub fn relations( }; for c in calls { receipt.harvested += 1; + let mut kythe_target = None; let (predicate, object) = match &c.callee { Callee::Fun(id) => match krate.fun_decls.get(*id) { Some(t) => ("CALLS_RESOLVED", qualified_name(krate, &t.item_meta.name)), @@ -373,6 +487,7 @@ pub fn relations( Callee::Trait { kind, trait_id, + method, impl_fun, } => { if kind == "TraitImpl" { @@ -398,7 +513,12 @@ pub fn relations( .and_then(|t| krate.item_names.get(&ItemId::TraitDecl(t))) .map(|n| qualified_name(krate, n)) .unwrap_or_else(|| "?".to_owned()); - ("MAY_DISPATCH", format!("{tr} via {kind}")) + let name = trait_id + .and_then(|t| krate.trait_decls.get(t)) + .and_then(|t| t.methods.get(*method)) + .map_or_else(|| "?".to_owned(), |m| m.skip_binder.name.to_string()); + kythe_target = Some(tr.clone()); + ("MAY_DISPATCH", format!("{tr}::{name} via {kind}")) } } Callee::Dynamic => ("UNRESOLVED_CALL", "dynamic".to_owned()), @@ -408,8 +528,32 @@ pub fn relations( subject: f.qualified.clone(), object, site: c.site, + kythe_target, }); } + for r in f.refs { + receipt.harvested += 1; + let named = r.target.and_then(|id| match krate.fun_decls.get(id) { + Some(t) => Some(qualified_name(krate, &t.item_meta.name)), + None => krate + .item_names + .get(&ItemId::Fun(id)) + .map(|n| qualified_name(krate, n)), + }); + match named { + Some(object) => rows.push(Relation { + predicate: "REFERENCES", + subject: f.qualified.clone(), + object, + site: r.site, + kythe_target: None, + }), + None => residual.push(Residual { + reason: "REFERENCE_NOT_NAMED", + subject: f.qualified.clone(), + }), + } + } } receipt.represented = rows.len(); receipt.residual = residual.len(); @@ -475,6 +619,14 @@ pub fn kythe_entries( let mut files = std::collections::HashSet::new(); let (rows, _, _) = relations(krate, crate_name); for r in rows { + // The v2 predicates are facts about items, not Kythe edges; emitting + // their anchors would change the entry stream. + if matches!( + r.predicate, + "PUBLIC" | "IMPLEMENTS" | "SYNTHETIC" | "REFERENCES" + ) { + continue; + } let Some(s) = &r.site else { continue }; if files.insert(s.file.clone()) && let Some(f) = krate.files.iter().find(|f| match &f.name { @@ -508,7 +660,10 @@ pub fn kythe_entries( ); } "CALLS_RESOLVED" | "MAY_DISPATCH" => { - let target = r.object.split(" via ").next().unwrap_or(&r.object); + let target = r + .kythe_target + .as_deref() + .unwrap_or_else(|| r.object.split(" via ").next().unwrap_or(&r.object)); let callee = vname(corpus, target, "", "rust"); emit( serde_json::json!({"source": a.clone(), "edge_kind": "/kythe/edge/ref/call", "target": callee, "fact_name": "/"}), diff --git a/crates/ruff_charon/src/store.rs b/crates/ruff_charon/src/store.rs index 25d90e4c09826..14b254c7a11db 100644 --- a/crates/ruff_charon/src/store.rs +++ b/crates/ruff_charon/src/store.rs @@ -28,7 +28,7 @@ use std::sync::atomic::{AtomicU64, Ordering}; use crate::{GRADE, Llbc, relations}; /// The version of the rows artifact this crate writes and reads. -pub const ROWS_VERSION: u32 = 1; +pub const ROWS_VERSION: u32 = 2; const ROWS_SCHEMA: &[&str] = &[ "predicate", "subject", @@ -238,6 +238,14 @@ impl Store { r.predicate, r.subject, r.object )?; } + // Whether Charon translated the whole crate: a PARTIAL crate's absent + // rows are not evidence of absence. + let completeness = if llbc.has_errors { + "PARTIAL" + } else { + "COMPLETE" + }; + writeln!(out, "CRATE\t{crate_name}\t{completeness}\t{GRADE}\t-\t-\t-")?; let mut res = Vec::new(); header(&mut res, RESIDUALS_VERSION, RESIDUALS_SCHEMA)?; for r in &residual { diff --git a/crates/ruff_charon/tests/data/fnref.llbc b/crates/ruff_charon/tests/data/fnref.llbc new file mode 100644 index 0000000000000..80fdf6d9e5496 --- /dev/null +++ b/crates/ruff_charon/tests/data/fnref.llbc @@ -0,0 +1 @@ +{"charon_version":"0.1.297","translated":{"crate_name":"fnref","options":{"ullbc":false,"no_code_duplication":false,"precise_drops":false,"mir":null,"rustc_args":[],"targets":[],"sysroot":null,"monomorphize":false,"monomorphize_mut":null,"start_from":[],"start_from_if_exists":[],"start_from_attribute":[],"start_from_pub":false,"include":[],"opaque":[],"exclude":[],"extract_opaque_bodies":false,"translate_all_methods":false,"eager_vtables":false,"duplicate_defaulted_methods":false,"lift_associated_types":[],"hide_marker_traits":false,"hide_allocator":false,"no_doc_comments":false,"remove_unused_clauses":false,"remove_unused_self_clauses":false,"remove_adt_clauses":false,"desugar_drops":false,"resugar_drops":false,"detect_drop_flags":false,"ops_to_function_calls":false,"index_to_function_calls":false,"treat_box_as_builtin":false,"no_gen_tuple_structs":false,"raw_consts":false,"inline_anon_consts":false,"consts":null,"unsized_strings":false,"reconstruct_fallible_operations":false,"reconstruct_panic_calls":false,"reconstruct_asserts":false,"reconstruct_matches":false,"deallocate_all_locals":false,"unbind_item_vars":false,"print_original_ullbc":false,"print_ullbc":false,"print_built_llbc":false,"print_llbc":false,"print_layouts":false,"print_safety":false,"dest_dir":null,"dest_file":"fnref.llbc","no_dedup_serialized_ast":true,"format":null,"run_with_minirust":false,"no_serialize":false,"skip_borrowck":false,"erase_body_lifetimes":false,"no_typecheck":false,"no_normalize":false,"no_reorder_decls":false,"no_compute_layout_guarantees":false,"abort_on_error":false,"error_on_warnings":false,"preset":null},"target_information":[{"key":"x86_64-unknown-linux-gnu","value":{"arch":"X86_64","vendor":"unknown","os":"Linux","env":"Gnu","cfg_abi":"Unspecified","target_pointer_size":8,"is_little_endian":true,"c_enum_smallest_repr_ty":"I32","primitive_alignments":[{"key":"Bool","value":1},{"key":{"Integer":{"Signed":"I8"}},"value":1},{"key":{"Integer":{"Signed":"I16"}},"value":2},{"key":{"Integer":{"Signed":"I32"}},"value":4},{"key":{"Integer":{"Signed":"I64"}},"value":8},{"key":{"Integer":{"Signed":"I128"}},"value":16},{"key":{"Integer":{"Signed":"Isize"}},"value":8},{"key":{"Integer":{"Unsigned":"U8"}},"value":1},{"key":{"Integer":{"Unsigned":"U16"}},"value":2},{"key":{"Integer":{"Unsigned":"U32"}},"value":4},{"key":{"Integer":{"Unsigned":"U64"}},"value":8},{"key":{"Integer":{"Unsigned":"U128"}},"value":16},{"key":{"Integer":{"Unsigned":"Usize"}},"value":8},{"key":{"Float":"F16"},"value":2},{"key":{"Float":"F32"},"value":4},{"key":{"Float":"F64"},"value":8},{"key":{"Float":"F128"},"value":16},{"key":"Char","value":4}]}}],"runtime_checks":{"ub_checks":true,"overflow_checks":true,"contract_checks":false},"files":[{"id":0,"name":{"Local":"fnref.rs"},"crate_name":"fnref","contents":"//! A function used only through a function pointer, an unused private\n//! function, and a call through a function-pointer argument.\nfn helper(x: u32) -> u32 {\n x + 1\n}\nfn unused_private() -> u32 {\n 0\n}\npub fn take() -> fn(u32) -> u32 {\n helper\n}\npub fn apply(f: fn(u32) -> u32) -> u32 {\n f(1)\n}\n"},{"id":1,"name":{"Local":"/rustc/library/core/src/lib.rs"},"crate_name":"core","contents":null},{"id":2,"name":{"Local":"/rustc/library/core/src/marker.rs"},"crate_name":"core","contents":null}],"item_names":[{"key":{"Type":0},"value":[{"Builtin":[{"Tuple":0},0]}]},{"key":{"Fun":0},"value":[{"Ident":["fnref",0]},{"Ident":["helper",0]}]},{"key":{"Fun":1},"value":[{"Ident":["fnref",0]},{"Ident":["unused_private",0]}]},{"key":{"Fun":2},"value":[{"Ident":["fnref",0]},{"Ident":["take",0]}]},{"key":{"Fun":3},"value":[{"Ident":["fnref",0]},{"Ident":["apply",0]}]},{"key":{"Type":1},"value":[{"Builtin":[{"Tuple":2},0]}]},{"key":{"TraitDecl":0},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["Sized",0]}]},{"key":{"TraitDecl":1},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]}]},{"key":{"Global":0},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]},{"Builtin":["VTable",0]}]},{"key":{"Type":2},"value":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]},{"Builtin":["VTable",0]}]}],"assoc_item_names":[{"types":[],"methods":[],"consts":[]},{"types":[],"methods":[],"consts":[]}],"short_names":[{"key":{"TraitDecl":0},"value":[{"Ident":["Sized",0]}]},{"key":{"TraitDecl":1},"value":[{"Ident":["MetaSized",0]}]},{"key":{"Global":0},"value":[{"Builtin":["VTable",0]}]},{"key":{"Type":2},"value":[{"Builtin":["VTable",0]}]},{"key":{"Fun":2},"value":[{"Ident":["take",0]}]},{"key":{"Fun":1},"value":[{"Ident":["unused_private",0]}]},{"key":{"Fun":3},"value":[{"Ident":["apply",0]}]},{"key":{"Fun":0},"value":[{"Ident":["helper",0]}]}],"type_decls":[null,{"def_id":1,"item_meta":{"name":[{"Builtin":[{"Tuple":2},0]}],"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":1,"col":0},"end":{"line":1,"col":0}},"generated_from_span":null}},"source_text":null,"attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":false,"started_from":false,"is_extern":false,"opacity":"Transparent","lang_item":null,"diagnostic_item":null,"has_errors":false},"generics":{"regions":[],"types":[{"index":0,"name":"A","variance":"Covariant"},{"index":1,"name":"B","variance":"Covariant"}],"const_generics":[],"trait_clauses":[{"clause_id":0,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":1,"col":0},"end":{"line":1,"col":0}},"generated_from_span":null}},"origin":"WhereClauseOnType","trait_":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[1,0]}}}],"const_generics":[],"trait_refs":[]}}}}],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"src":{"Builtin":"Tuple"},"kind":{"Struct":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":1,"col":0},"end":{"line":1,"col":0}},"generated_from_span":null}},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"_0","is_positional":true,"ty":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":1,"col":0},"end":{"line":1,"col":0}},"generated_from_span":null}},"attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"name":"_1","is_positional":true,"ty":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}}]},"layout":[{"key":"x86_64-unknown-linux-gnu","value":{"size":{"chosen":null,"guarantee":{"Untagged":{"AtLeast":{"Untagged":{"AlignTo":{"base":{"Untagged":{"Max":[{"Untagged":{"Plus":[{"Untagged":{"Constant":{"Untagged":[{"OffsetOf":[{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[0,0]}}},{"Untagged":{"TypeVar":{"Bound":[0,1]}}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"Clause":[{"Bound":[1,0]},{"regions":[]}]},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[1,0]}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"},null,0]},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}},{"Untagged":{"Constant":{"Untagged":[{"SizeOf":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}]}},{"Untagged":{"Plus":[{"Untagged":{"Constant":{"Untagged":[{"OffsetOf":[{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[0,0]}}},{"Untagged":{"TypeVar":{"Bound":[0,1]}}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"Clause":[{"Bound":[1,0]},{"regions":[]}]},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[1,0]}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"},null,1]},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}},{"Untagged":{"Constant":{"Untagged":[{"SizeOf":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}]}}]}},"target_align":{"Untagged":{"Max":[{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}},{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}]}}}}}}}},"align":{"chosen":null,"guarantee":{"Untagged":{"AtLeast":{"Untagged":{"Max":[{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}},{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}]}}}}},"discriminator":null,"inhabited":{"Untagged":{"And":[{"Untagged":{"GenericType":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}}},{"Untagged":{"GenericType":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}}}]}},"variant_layouts":[{"field_offsets":[{"guarantee":{"GuaranteedAlignment":{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}},"chosen":null},{"guarantee":{"GuaranteedAlignment":{"Untagged":{"Constant":{"Untagged":[{"AlignOf":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"Usize"}}}}]}}}},"chosen":null}],"inhabited":{"Untagged":{"And":[{"Untagged":{"GenericType":{"Untagged":{"TypeVar":{"Bound":[0,0]}}}}},{"Untagged":{"GenericType":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}}}]}},"tagger":[]}],"repr":{"repr_algo":"Rust","align_modif":null,"transparent":false,"explicit_discr_type":null}}}],"ptr_metadata":{"InheritFrom":{"Untagged":{"TypeVar":{"Bound":[0,1]}}}},"marker_traits":null},null],"fun_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["fnref",0]},{"Ident":["helper",0]}],"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":0},"end":{"line":5,"col":1}},"generated_from_span":null}},"source_text":"fn helper(x: u32) -> u32 {\n x + 1\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":true,"started_from":true,"is_extern":false,"opacity":"Transparent","lang_item":null,"diagnostic_item":null,"has_errors":false},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"signature":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},"src":"Normal","body":{"Structured":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":0},"end":{"line":5,"col":1}},"generated_from_span":null}},"bound_body_regions":0,"locals":{"arg_count":1,"locals":[{"index":0,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":21},"end":{"line":3,"col":24}},"generated_from_span":null}},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},"drop_flag_for":null},{"index":1,"name":"x","span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":10},"end":{"line":3,"col":11}},"generated_from_span":null}},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},"drop_flag_for":null},{"index":2,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":5}},"generated_from_span":null}},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},"drop_flag_for":null},{"index":3,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":9}},"generated_from_span":null}},"ty":{"Untagged":{"Adt":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},{"Untagged":{"Scalar":"Bool"}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"Sized","parent_trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"MetaSized","parent_trait_refs":[],"types":[],"vtable":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}},"trait_decl_ref":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}],"types":[],"vtable":null}},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"}}},"drop_flag_for":null}]},"body":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":5,"col":1}},"generated_from_span":null}},"id":4,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":5}},"generated_from_span":null}},"id":0,"kind":{"StorageLive":0},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":5}},"generated_from_span":null}},"id":1,"kind":{"StorageLive":3},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":5}},"generated_from_span":null}},"id":2,"kind":{"StorageLive":2},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":5}},"generated_from_span":null}},"id":3,"kind":{"Assign":[{"kind":{"Local":2},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},{"Use":[{"Copy":{"kind":{"Local":1},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}},"Yes"]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":9}},"generated_from_span":null}},"id":4,"kind":{"Assign":[{"kind":{"Local":3},"ty":{"Untagged":{"Adt":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},{"Untagged":{"Scalar":"Bool"}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"Sized","parent_trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"MetaSized","parent_trait_refs":[],"types":[],"vtable":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}},"trait_decl_ref":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}],"types":[],"vtable":null}},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"}}}},{"BinaryOp":["AddChecked",{"Copy":{"kind":{"Local":2},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}},{"Const":{"Untagged":[{"Integer":{"Unsigned":["U32","1"]}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}]}}]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":9}},"generated_from_span":null}},"id":9,"kind":{"Assert":{"assert":{"cond":{"Move":{"kind":{"Projection":[{"kind":{"Local":3},"ty":{"Untagged":{"Adt":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},{"Untagged":{"Scalar":"Bool"}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"Sized","parent_trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"MetaSized","parent_trait_refs":[],"types":[],"vtable":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}},"trait_decl_ref":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}],"types":[],"vtable":null}},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"}}}},{"Field":[null,1]}]},"ty":{"Untagged":{"Scalar":"Bool"}}}},"expected":false,"check_kind":{"Overflow":[{"Add":"Wrap"},{"Move":{"kind":{"Local":2},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}},{"Const":{"Untagged":[{"Integer":{"Unsigned":["U32","1"]}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}]}}]}},"on_failure":{"Panic":null},"on_unwind":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":0},"end":{"line":5,"col":1}},"generated_from_span":null}},"id":0,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":3,"col":0},"end":{"line":5,"col":1}},"generated_from_span":null}},"id":5,"kind":"UnwindResume","comments_before":[]}]}}},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":4},"end":{"line":4,"col":9}},"generated_from_span":null}},"id":6,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},{"Use":[{"Move":{"kind":{"Projection":[{"kind":{"Local":3},"ty":{"Untagged":{"Adt":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},{"Untagged":{"Scalar":"Bool"}}],"const_generics":[],"trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"Sized","parent_trait_refs":[{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"Untagged":{"kind":{"BuiltinOrAuto":{"builtin_data":"MetaSized","parent_trait_refs":[],"types":[],"vtable":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}},"trait_decl_ref":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}],"types":[],"vtable":null}},"trait_decl_ref":{"id":0,"generics":{"regions":[],"types":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"const_generics":[],"trait_refs":[]}}}}}]},"builtin":"Tuple"}}}},{"Field":[null,0]}]},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}},"Yes"]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":4,"col":8},"end":{"line":4,"col":9}},"generated_from_span":null}},"id":7,"kind":{"StorageDead":2},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":5,"col":1},"end":{"line":5,"col":1}},"generated_from_span":null}},"id":8,"kind":"Return","comments_before":[]}]},"comments":[]}}},{"def_id":1,"item_meta":{"name":[{"Ident":["fnref",0]},{"Ident":["unused_private",0]}],"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":6,"col":0},"end":{"line":8,"col":1}},"generated_from_span":null}},"source_text":"fn unused_private() -> u32 {\n 0\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":false},"is_local":true,"started_from":true,"is_extern":false,"opacity":"Transparent","lang_item":null,"diagnostic_item":null,"has_errors":false},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"signature":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},"src":"Normal","body":{"Structured":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":6,"col":0},"end":{"line":8,"col":1}},"generated_from_span":null}},"bound_body_regions":0,"locals":{"arg_count":0,"locals":[{"index":0,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":6,"col":23},"end":{"line":6,"col":26}},"generated_from_span":null}},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},"drop_flag_for":null}]},"body":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":7,"col":4},"end":{"line":8,"col":1}},"generated_from_span":null}},"id":6,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":7,"col":4},"end":{"line":7,"col":5}},"generated_from_span":null}},"id":10,"kind":{"StorageLive":0},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":7,"col":4},"end":{"line":7,"col":5}},"generated_from_span":null}},"id":11,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},{"Use":[{"Const":{"Untagged":[{"Integer":{"Unsigned":["U32","0"]}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}]}},"Yes"]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":8,"col":1},"end":{"line":8,"col":1}},"generated_from_span":null}},"id":12,"kind":"Return","comments_before":[]}]},"comments":[]}}},{"def_id":2,"item_meta":{"name":[{"Ident":["fnref",0]},{"Ident":["take",0]}],"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":9,"col":0},"end":{"line":11,"col":1}},"generated_from_span":null}},"source_text":"pub fn take() -> fn(u32) -> u32 {\n helper\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"started_from":true,"is_extern":false,"opacity":"Transparent","lang_item":null,"diagnostic_item":null,"has_errors":false},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"signature":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[],"output":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}},"src":"Normal","body":{"Structured":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":9,"col":0},"end":{"line":11,"col":1}},"generated_from_span":null}},"bound_body_regions":0,"locals":{"arg_count":0,"locals":[{"index":0,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":9,"col":17},"end":{"line":9,"col":31}},"generated_from_span":null}},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}},"drop_flag_for":null}]},"body":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":10,"col":4},"end":{"line":11,"col":1}},"generated_from_span":null}},"id":8,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":10,"col":4},"end":{"line":10,"col":10}},"generated_from_span":null}},"id":13,"kind":{"StorageLive":0},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":10,"col":4},"end":{"line":10,"col":10}},"generated_from_span":null}},"id":14,"kind":{"Assign":[{"kind":{"Local":0},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}},{"UnaryOp":[{"Cast":"FnDefToFnPtr"},{"Const":{"Untagged":[{"FnDef":{"kind":{"Fun":0},"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}},{"Untagged":{"FnDef":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"kind":{"Fun":0},"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]}}}}}]}}]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":11,"col":1},"end":{"line":11,"col":1}},"generated_from_span":null}},"id":15,"kind":"Return","comments_before":[]}]},"comments":[]}}},{"def_id":3,"item_meta":{"name":[{"Ident":["fnref",0]},{"Ident":["apply",0]}],"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":0},"end":{"line":14,"col":1}},"generated_from_span":null}},"source_text":"pub fn apply(f: fn(u32) -> u32) -> u32 {\n f(1)\n}","attr_info":{"attributes":[],"inline":null,"rename":null,"public":true},"is_local":true,"started_from":true,"is_extern":false,"opacity":"Transparent","lang_item":null,"diagnostic_item":null,"has_errors":false},"generics":{"regions":[],"types":[],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"signature":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},"src":"Normal","body":{"Structured":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":0},"end":{"line":14,"col":1}},"generated_from_span":null}},"bound_body_regions":0,"locals":{"arg_count":1,"locals":[{"index":0,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":35},"end":{"line":12,"col":38}},"generated_from_span":null}},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}},"drop_flag_for":null},{"index":1,"name":"f","span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":13},"end":{"line":12,"col":14}},"generated_from_span":null}},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}},"drop_flag_for":null},{"index":2,"name":null,"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":5}},"generated_from_span":null}},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}},"drop_flag_for":null}]},"body":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":14,"col":1}},"generated_from_span":null}},"id":12,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":5}},"generated_from_span":null}},"id":16,"kind":{"StorageLive":0},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":5}},"generated_from_span":null}},"id":17,"kind":{"StorageLive":2},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":5}},"generated_from_span":null}},"id":18,"kind":{"Assign":[{"kind":{"Local":2},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}},{"Use":[{"Copy":{"kind":{"Local":1},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}}},"Yes"]}]},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":4},"end":{"line":13,"col":8}},"generated_from_span":null}},"id":20,"kind":{"Call":{"call":{"func":{"Dynamic":[{"Move":{"kind":{"Local":2},"ty":{"Untagged":{"FnPtr":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"is_unsafe":false,"abi":"Rust","is_variadic":false,"inputs":[{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}],"output":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}}}}}}},{"regions":[]}]},"args":[{"Const":{"Untagged":[{"Integer":{"Unsigned":["U32","1"]}},{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}]}}],"dest":{"kind":{"Local":0},"ty":{"Untagged":{"Scalar":{"Integer":{"Unsigned":"U32"}}}}},"safety":"Inherit"},"on_unwind":{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":0},"end":{"line":14,"col":1}},"generated_from_span":null}},"id":9,"statements":[{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":12,"col":0},"end":{"line":14,"col":1}},"generated_from_span":null}},"id":19,"kind":"UnwindResume","comments_before":[]}]}}},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":13,"col":7},"end":{"line":13,"col":8}},"generated_from_span":null}},"id":21,"kind":{"StorageDead":2},"comments_before":[]},{"span":{"Untagged":{"data":{"file_id":0,"beg":{"line":14,"col":1},"end":{"line":14,"col":1}},"generated_from_span":null}},"id":22,"kind":"Return","comments_before":[]}]},"comments":[]}}}],"global_decls":[null],"trait_decls":[{"def_id":0,"item_meta":{"name":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["Sized",0]}],"span":{"Untagged":{"data":{"file_id":2,"beg":{"line":158,"col":0},"end":{"line":158,"col":26}},"generated_from_span":null}},"source_text":null,"attr_info":{"attributes":[{"DocComment":" Types with a constant size known at compile time."},{"DocComment":""},{"DocComment":" All type parameters have an implicit bound of `Sized`. The special syntax"},{"DocComment":" `?Sized` can be used to remove this bound if it's not appropriate."},{"DocComment":""},{"DocComment":" ```"},{"DocComment":" # #![allow(dead_code)]"},{"DocComment":" struct Foo(T);"},{"DocComment":" struct Bar(T);"},{"DocComment":""},{"DocComment":" // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32]"},{"DocComment":" struct BarUse(Bar<[i32]>); // OK"},{"DocComment":" ```"},{"DocComment":""},{"DocComment":" The one exception is the implicit `Self` type of a trait. A trait does not"},{"DocComment":" have an implicit `Sized` bound as this is incompatible with [trait object]s"},{"DocComment":" where, by definition, the trait needs to work with all possible implementors,"},{"DocComment":" and thus could be any size."},{"DocComment":""},{"DocComment":" Although Rust will let you bind `Sized` to a trait, you won't"},{"DocComment":" be able to use it to form a trait object later:"},{"DocComment":""},{"DocComment":" ```"},{"DocComment":" # #![allow(unused_variables)]"},{"DocComment":" trait Foo { }"},{"DocComment":" trait Bar: Sized { }"},{"DocComment":""},{"DocComment":" struct Impl;"},{"DocComment":" impl Foo for Impl { }"},{"DocComment":" impl Bar for Impl { }"},{"DocComment":""},{"DocComment":" let x: &dyn Foo = &Impl; // OK"},{"DocComment":" // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot be made into an object"},{"DocComment":" ```"},{"DocComment":""},{"DocComment":" [trait object]: ../../book/ch17-02-trait-objects.html"},{"Builtin":"Fundamental"}],"inline":null,"rename":null,"public":true},"is_local":false,"started_from":false,"is_extern":false,"opacity":"Foreign","lang_item":"Sized","diagnostic_item":null,"has_errors":false},"src":"Normal","is_unsafe":false,"generics":{"regions":[],"types":[{"index":0,"name":"Self","variance":"Unknown"}],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"implied_clauses":[{"clause_id":0,"span":{"Untagged":{"data":{"file_id":2,"beg":{"line":158,"col":17},"end":{"line":158,"col":26}},"generated_from_span":null}},"origin":"WhereClauseOnTrait","trait_":{"regions":[],"regions_outlive":[],"types_outlive":[],"skip_binder":{"id":1,"generics":{"regions":[],"types":[{"Untagged":{"TypeVar":{"Bound":[1,0]}}}],"const_generics":[],"trait_refs":[]}}}}],"consts":[],"types":[],"methods":[],"vtable":null},{"def_id":1,"item_meta":{"name":[{"Ident":["core",0]},{"Ident":["marker",0]},{"Ident":["MetaSized",0]}],"span":{"Untagged":{"data":{"file_id":2,"beg":{"line":175,"col":0},"end":{"line":175,"col":33}},"generated_from_span":null}},"source_text":null,"attr_info":{"attributes":[{"DocComment":" Types with a size that can be determined from pointer metadata."},{"Builtin":"Fundamental"}],"inline":null,"rename":null,"public":true},"is_local":false,"started_from":false,"is_extern":false,"opacity":"Foreign","lang_item":"MetaSized","diagnostic_item":null,"has_errors":false},"src":"Normal","is_unsafe":false,"generics":{"regions":[],"types":[{"index":0,"name":"Self","variance":"Unknown"}],"const_generics":[],"trait_clauses":[],"regions_outlive":[],"types_outlive":[],"trait_type_constraints":[]},"implied_clauses":[],"consts":[],"types":[],"methods":[],"vtable":{"id":2,"generics":{"regions":[],"types":[],"const_generics":[],"trait_refs":[]},"builtin":null}}],"trait_impls":[],"ordered_decls":[{"TraitDecl":{"NonRec":1}},{"TraitDecl":{"NonRec":0}},{"Type":{"NonRec":1}},{"Fun":{"NonRec":0}},{"Fun":{"NonRec":1}},{"Fun":{"NonRec":2}},{"Fun":{"NonRec":3}}]},"has_errors":false} \ No newline at end of file diff --git a/crates/ruff_charon/tests/data/fnref.rs b/crates/ruff_charon/tests/data/fnref.rs new file mode 100644 index 0000000000000..642dc3b5b3d85 --- /dev/null +++ b/crates/ruff_charon/tests/data/fnref.rs @@ -0,0 +1,14 @@ +//! A function used only through a function pointer, an unused private +//! function, and a call through a function-pointer argument. +fn helper(x: u32) -> u32 { + x + 1 +} +fn unused_private() -> u32 { + 0 +} +pub fn take() -> fn(u32) -> u32 { + helper +} +pub fn apply(f: fn(u32) -> u32) -> u32 { + f(1) +} diff --git a/crates/ruff_charon/tests/intake.rs b/crates/ruff_charon/tests/intake.rs index e15697f60a02f..6f302a5385c13 100644 --- a/crates/ruff_charon/tests/intake.rs +++ b/crates/ruff_charon/tests/intake.rs @@ -46,7 +46,7 @@ fn dispatch_is_never_a_confirmed_call() { let rows = rows("cg_lib.llbc", "cg_lib"); let bound = find(&rows, "MAY_DISPATCH", "cg_lib::area_of"); assert_eq!(bound.len(), 1, "{rows:#?}"); - assert_eq!(bound[0].object, "cg_lib::shapes::Shape via Clause"); + assert_eq!(bound[0].object, "cg_lib::shapes::Shape::area via Clause"); assert!(find(&rows, "CALLS_RESOLVED", "cg_lib::area_of").is_empty()); let dynamic = find(&rows, "UNRESOLVED_CALL", "cg_lib::area_dyn"); assert_eq!(dynamic.len(), 1); @@ -104,8 +104,9 @@ fn receipt_conserves() { assert!(receipt.conserved(), "{receipt:?}"); assert_eq!(receipt.represented, rows.len()); assert_eq!(receipt.residual, residual.len()); - // 11 local functions, 5 call statements (llbc_calls.py's count). - assert_eq!(receipt.harvested, 16); + // 11 local functions, 5 call statements (llbc_calls.py's count), and + // the rows v2 facts: 9 PUBLIC, 2 IMPLEMENTS, 1 SYNTHETIC. + assert_eq!(receipt.harvested, 28); } /// The Kythe entries carry the macro call as a `ref/call` anchor and the diff --git a/crates/ruff_charon/tests/intake_v2.rs b/crates/ruff_charon/tests/intake_v2.rs new file mode 100644 index 0000000000000..76c9c447784b8 --- /dev/null +++ b/crates/ruff_charon/tests/intake_v2.rs @@ -0,0 +1,149 @@ +//! Rows v2 on the codegraph fixture (lance-graph +//! `crates/sag-ra-probe/fixtures/codegraph/rev1`): `PUBLIC`, `IMPLEMENTS`, +//! `SYNTHETIC`, `REFERENCES`, and the method-qualified `MAY_DISPATCH` object. + +use std::path::{Path, PathBuf}; + +use ruff_charon::{Relation, kythe_entries, load, relations}; + +fn data(name: &str) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .join("tests/data") + .join(name) +} + +fn lib_rows() -> (Vec, ruff_charon::Receipt) { + let llbc = load(&data("cg_lib.llbc")).expect("llbc"); + let (rows, _, receipt) = relations(&llbc.krate, "cg_lib"); + (rows, receipt) +} + +fn count(rows: &[Relation], predicate: &str) -> usize { + rows.iter().filter(|r| r.predicate == predicate).count() +} + +/// Fails when a `pub fn` is not marked public, or a private item is. The +/// fixture has seven `pub fn`s and the private `private_unused`; Charon also +/// marks the two `Shape::area` impl methods public (a trait impl's methods +/// take the trait's visibility), and this transcribes Charon's flag as is. +#[test] +fn public_functions_are_marked() { + let (rows, _) = lib_rows(); + let mut public: Vec<_> = rows + .iter() + .filter(|r| r.predicate == "PUBLIC") + .map(|r| r.subject.as_str()) + .collect(); + public.sort_unstable(); + assert_eq!( + public, + [ + "cg_lib::area_dyn", + "cg_lib::area_of", + "cg_lib::macro_use::checked", + "cg_lib::shapes::impl_Shape_for_Rect::area", + "cg_lib::shapes::impl_Shape_for_Square::area", + "cg_lib::shapes::{Square}::side", + "cg_lib::util::double", + "cg_lib::util::triple", + "cg_lib::util::unit", + ] + ); +} + +/// Fails when a function used only as a function pointer has no reference +/// row (it would read as dead), or when a call through a pointer argument is +/// named instead of left unresolved. +#[test] +fn a_function_pointer_use_is_a_reference() { + let llbc = load(&data("fnref.llbc")).expect("llbc"); + let (rows, residual, receipt) = relations(&llbc.krate, "fnref"); + assert!(receipt.conserved(), "{receipt:?}"); + assert!(residual.is_empty(), "{residual:?}"); + let refs: Vec<_> = rows + .iter() + .filter(|r| r.predicate == "REFERENCES") + .map(|r| (r.subject.as_str(), r.object.as_str())) + .collect(); + assert_eq!(refs, [("fnref::take", "fnref::helper")]); + let unresolved: Vec<_> = rows + .iter() + .filter(|r| r.predicate == "UNRESOLVED_CALL") + .map(|r| r.subject.as_str()) + .collect(); + assert_eq!(unresolved, ["fnref::apply"]); +} + +/// Fails when a trait-impl method does not name the trait method it +/// implements, or when the trait's method name is dropped. +#[test] +fn impl_methods_name_the_trait_method() { + let (rows, _) = lib_rows(); + let implements: Vec<_> = rows + .iter() + .filter(|r| r.predicate == "IMPLEMENTS") + .collect(); + assert_eq!(implements.len(), 2, "{implements:#?}"); + assert!( + implements + .iter() + .all(|r| r.object == "cg_lib::shapes::Shape::area") + ); +} + +/// Fails when the compiler-made `{promoted_const}` item of `checked` is not +/// flagged, or when ordinary identifier and impl paths are. +#[test] +fn synthetic_items_are_flagged() { + let (rows, _) = lib_rows(); + assert_eq!(count(&rows, "SYNTHETIC"), 1, "{rows:#?}"); +} + +/// Fails when the dispatch object loses the method name, or when the Kythe +/// target stops being the plain trait name. +#[test] +fn may_dispatch_names_the_method_and_keeps_the_kythe_target() { + let (rows, _) = lib_rows(); + let dispatch: Vec<_> = rows + .iter() + .filter(|r| r.predicate == "MAY_DISPATCH") + .collect(); + assert_eq!(dispatch.len(), 1, "{dispatch:#?}"); + assert_eq!(dispatch[0].object, "cg_lib::shapes::Shape::area via Clause"); + assert_eq!( + dispatch[0].kythe_target.as_deref(), + Some("cg_lib::shapes::Shape") + ); + assert!( + rows.iter() + .filter(|r| r.predicate != "MAY_DISPATCH") + .all(|r| r.kythe_target.is_none()) + ); +} + +/// Fails when a called function is reported as merely referenced: the +/// fixture takes no function as a value. +#[test] +fn called_functions_are_not_references() { + let (rows, receipt) = lib_rows(); + assert_eq!(count(&rows, "REFERENCES"), 0, "{rows:#?}"); + assert!(receipt.conserved(), "{receipt:?}"); +} + +/// Fails when the v2 predicates change a single Kythe entry. +#[test] +#[expect( + clippy::disallowed_methods, + reason = "a test reading its own data file; the ty `System` abstraction does not apply here" +)] +fn kythe_output_is_unchanged_by_v2() { + for (file, krate) in [("cg_lib", "cg_lib"), ("cg_app", "cg_app")] { + let llbc = load(&data(&format!("{file}.llbc"))).expect("llbc"); + let want = std::fs::read_to_string(data(&format!("{file}.kythe.golden"))).expect("golden"); + // The `kythe` command's defaults: corpus `lance-graph`, nothing stripped, + // one entry per line. + let mut got = kythe_entries(&llbc.krate, krate, "lance-graph", "").join("\n"); + got.push('\n'); + assert_eq!(got, want, "{file}"); + } +} diff --git a/crates/ruff_charon/tests/store.rs b/crates/ruff_charon/tests/store.rs index 13f6f1b3372a0..19616e369e5e3 100644 --- a/crates/ruff_charon/tests/store.rs +++ b/crates/ruff_charon/tests/store.rs @@ -197,7 +197,7 @@ fn readers_refuse_unknown_versions_and_missing_columns() { .join(format!("ruff_charon_reader_{}", std::process::id())) .join("cg_lib.rows.tsv"); let text = std::fs::read_to_string(&path).expect("rows file"); - std::fs::write(&path, text.replacen("#version 1", "#version 2", 1)).expect("write"); + std::fs::write(&path, text.replacen("#version 2", "#version 3", 1)).expect("write"); assert!( store.rows("cg_lib").is_err(), "a newer version must be refused" From f55d863f7e0d8c79899ccec5dbb9aee20d9496c5 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 06:45:15 +0000 Subject: [PATCH 3/4] ruff_charon: test the crate status row; README for fnref and the goldens Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01X6y3drwKSE2zSgoexheLFX --- crates/ruff_charon/tests/data/README.md | 4 ++++ crates/ruff_charon/tests/store.rs | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/crates/ruff_charon/tests/data/README.md b/crates/ruff_charon/tests/data/README.md index 48411f79ee302..61754ede1d4f3 100644 --- a/crates/ruff_charon/tests/data/README.md +++ b/crates/ruff_charon/tests/data/README.md @@ -11,3 +11,7 @@ The LLBC was produced with the AdaWorldAPI Charon fork (`c69e231`, toolchain `ni cd cg_lib && charon cargo --no-dedup-serialized-ast --dest-file cg_lib.llbc cd cg_app && charon cargo --no-dedup-serialized-ast --dest-file cg_app.llbc ``` + +- `fnref.llbc`: Charon LLBC of `fnref.rs` (a function used only as a function pointer, an unused private function, and a call through a pointer argument), produced with `charon rustc --no-dedup-serialized-ast --dest-file fnref.llbc -- --crate-type=lib fnref.rs`. rustc reports `dead_code` for `unused_private` only. +- `cg_lib.kythe.golden`, `cg_app.kythe.golden`: `ruff_charon kythe ` on rows v1 (before the v2 predicates); the v2 Kythe output must equal them. +- `cg_broken` (rev1) produces no LLBC: rustc stops on E0425 and E0432 before Charon translates, so a `CRATE … PARTIAL` row cannot come from a crate that does not compile. diff --git a/crates/ruff_charon/tests/store.rs b/crates/ruff_charon/tests/store.rs index 19616e369e5e3..275e3704b96a2 100644 --- a/crates/ruff_charon/tests/store.rs +++ b/crates/ruff_charon/tests/store.rs @@ -308,3 +308,27 @@ fn leftover_temporary_files_do_not_block_an_import() { .expect("rows") ); } + +/// The crate row records whether Charon reported errors, so a reader can tell +/// a crate whose absent rows are evidence of absence from one that is partial. +#[test] +fn the_crate_row_records_charon_errors() { + let status = |has_errors: bool| { + let store = Store::new(temp(&format!("crate_status_{has_errors}"))); + let mut l = llbc("cg_lib.llbc"); + l.has_errors = has_errors; + store.import(&l, "cg_lib").expect("import"); + store + .rows("cg_lib") + .expect("rows") + .into_iter() + .filter(|r| r.predicate == "CRATE") + .map(|r| (r.subject, r.object)) + .collect::>() + }; + assert_eq!( + status(false), + [("cg_lib".to_owned(), "COMPLETE".to_owned())] + ); + assert_eq!(status(true), [("cg_lib".to_owned(), "PARTIAL".to_owned())]); +} From 8846d814c1e504643197afe367e7eed35f511b71 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 06:46:16 +0000 Subject: [PATCH 4/4] ruff_charon: test that a reference never reaches Kythe Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01X6y3drwKSE2zSgoexheLFX --- crates/ruff_charon/tests/intake_v2.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/ruff_charon/tests/intake_v2.rs b/crates/ruff_charon/tests/intake_v2.rs index 76c9c447784b8..7eead1be2786c 100644 --- a/crates/ruff_charon/tests/intake_v2.rs +++ b/crates/ruff_charon/tests/intake_v2.rs @@ -147,3 +147,29 @@ fn kythe_output_is_unchanged_by_v2() { assert_eq!(got, want, "{file}"); } } + +/// Fails when a v2 predicate reaches Kythe. The goldens cannot catch this: +/// a PUBLIC/IMPLEMENTS/SYNTHETIC row carries its function's DEFINES span, and +/// the emitter drops duplicate entries. A REFERENCES row has a span of its +/// own (`helper` in `take`, bytes 247..253), so only it shows the leak. +#[test] +fn a_reference_is_not_a_kythe_anchor() { + let llbc = load(&data("fnref.llbc")).expect("llbc"); + let (rows, _, _) = relations(&llbc.krate, "fnref"); + let site = rows + .iter() + .find(|r| r.predicate == "REFERENCES") + .and_then(|r| r.site.as_ref()) + .expect("a reference site"); + assert_eq!((site.start, site.end), (247, 253)); + let at = format!("\"signature\":\"@{}:{}\"", site.start, site.end); + let entries = kythe_entries(&llbc.krate, "fnref", "lance-graph", ""); + assert!( + !entries.is_empty(), + "the crate's own anchors must be emitted" + ); + assert!( + entries.iter().all(|e| !e.contains(&at)), + "an anchor was emitted at the reference site" + ); +}