From 8a3d104167adc1bc2fb31c8509b9423f39303d12 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Sat, 07 Feb 2026 14:12:35 +0000 Subject: [PATCH] build: merge dependency updates --- --- a/Cargo.lock +++ b/Cargo.lock @@ -1,27 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "ahash" -version = "0.8.12" +name = "aho-corasick" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", + "memchr", ] [[package]] -name = "aho-corasick" -version = "1.1.3" +name = "aliasable" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" @@ -31,19 +25,30 @@ [[package]] name = "annotate-snippets" -version = "0.10.2" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9b665789884a7e8fb06c84b295e923b03ca51edbb7d08f91a6a50322ecbfe6" +checksum = "16e4850548ff4a25a77ce3bda7241874e17fb702ea551f0cc62a2dbe052f1272" dependencies = [ "anstyle", "unicode-width", ] [[package]] +name = "annotated-string" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298ed730801db3c02f2edba003c9420a0f57ea48d37fdc5601c536113668c059" +dependencies = [ + "hi-doc-jumprope", + "itertools", + "ouroboros", +] + +[[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -56,9 +61,9 @@ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -71,31 +76,40 @@ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] +name = "ar_archive_writer" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" +dependencies = [ + "object", +] + +[[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -108,16 +122,10 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" - -[[package]] name = "bitflags" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -130,30 +138,34 @@ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +dependencies = [ + "allocator-api2", +] [[package]] name = "cc" -version = "1.2.33" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clap" -version = "4.5.45" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" dependencies = [ "clap_builder", "clap_derive", @@ -161,9 +173,9 @@ [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" dependencies = [ "anstream", "anstyle", @@ -173,20 +185,20 @@ [[package]] name = "clap_complete" -version = "4.5.57" +version = "4.5.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d9501bd3f5f09f7bbee01da9a511073ed30a80cd7a509f1214bb74eadea71ad" +checksum = "430b4dc2b5e3861848de79627b2bedc9f3342c7da5173a14eaa5d0f8dc18ae5d" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn", @@ -194,9 +206,9 @@ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "colorchoice" @@ -233,9 +245,9 @@ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -259,14 +271,15 @@ [[package]] name = "dprint-core" -version = "0.65.0" +version = "0.67.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b569f4e3085ae957ecc37588e6b2227791b72745434eae966db29e122ba27f0d" +checksum = "2c1d827947704a9495f705d6aeed270fa21a67f825f22902c28f38dc3af7a9ae" dependencies = [ "anyhow", "bumpalo", - "indexmap 2.10.0", - "rustc-hash", + "hashbrown 0.15.5", + "indexmap", + "rustc-hash 2.1.1", "serde", "unicode-width", ] @@ -297,12 +310,23 @@ [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "extension-trait" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd65f1b59dd22d680c7a626cc4a000c1e03d241c51c3e034d2bc9f1e90734f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -312,6 +336,12 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -324,6 +354,12 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] name = "generic-array" version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -335,131 +371,137 @@ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.2.0", ] [[package]] name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hi-doc" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2390a0c9be1370168ef9557833bad3bfa37e1720df61d7f7034f18c07b4e006" +checksum = "f70fb920ba34768415fb239d7d607486083bfc38ad35e3f1d558697f9f646f11" dependencies = [ + "annotated-string", + "extension-trait", + "itertools", "num-traits", "rand", "random_color", "range-map", "smallvec", + "tree-sitter-highlight", + "unicode-box-drawing", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "hi-doc-jumprope" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "236c25809a9c0a0249b3488feb57744e12aa64e4f3db851980eab303719c7bdd" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "rand", + "str_indices", ] [[package]] name = "indexmap" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "serde", + "serde_core", ] [[package]] name = "indoc" -version = "2.0.6" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] [[package]] name = "insta" -version = "1.43.1" +version = "1.46.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "154934ea70c58054b556dd430b99a98c2a7ff5309ac9891597e339b5c28f4371" +checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4" dependencies = [ "console", "once_cell", "similar", + "tempfile", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jrsonnet" @@ -495,7 +537,6 @@ dependencies = [ "annotate-snippets", "anyhow", - "hashbrown 0.14.5", "hi-doc", "jrsonnet-gcmodule", "jrsonnet-interner", @@ -504,7 +545,8 @@ "jrsonnet-types", "num-bigint", "pathdiff", - "rustc-hash", + "rustc-hash 2.1.1", + "rustversion", "serde", "stacker", "static_assertions", @@ -528,18 +570,14 @@ [[package]] name = "jrsonnet-gcmodule" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87122f4aa9b77c38f96e43d9ba4b7717d63aa87b137090a16ec0107cf17abdac" +version = "0.4.0" dependencies = [ "jrsonnet-gcmodule-derive", ] [[package]] name = "jrsonnet-gcmodule-derive" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17eefaaba135591284e11cda15ed067247bec5fe9ece4fabc2c0df650d7b955a" +version = "0.4.0" dependencies = [ "proc-macro2", "quote", @@ -550,9 +588,9 @@ name = "jrsonnet-interner" version = "0.5.0-pre97" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.16.1", "jrsonnet-gcmodule", - "rustc-hash", + "rustc-hash 2.1.1", ] [[package]] @@ -601,7 +639,7 @@ "md5", "num-bigint", "regex", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "serde_json", "serde_yaml_with_quirks", @@ -620,9 +658,9 @@ [[package]] name = "json-structural-diff" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25c7940d3c84d2079306c176c7b2b37622b6bc5e43fbd1541b1e4a4e1fd02045" +checksum = "e878e36a8a44c158505c2c818abdc1350413ad83dcb774a0459f6a7ef2b65cbf" dependencies = [ "difflib", "regex", @@ -637,18 +675,12 @@ dependencies = [ "cpufeatures", ] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libjsonnet" @@ -662,79 +694,63 @@ ] [[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "logos" -version = "0.14.4" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" +checksum = "eb2c55a318a87600ea870ff8c2012148b44bf18b74fad48d0f835c38c7d07c5f" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.4" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" +checksum = "58b3ffaa284e1350d017a57d04ada118c4583cf260c8fb01e0fe28a2e9cf8970" dependencies = [ - "beef", "fnv", - "lazy_static", "proc-macro2", "quote", + "regex-automata", "regex-syntax", "syn", ] [[package]] name = "logos-derive" -version = "0.14.4" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" +checksum = "52d3a9855747c17eaf4383823f135220716ab49bea5fbea7dd42cc9a92f8aa31" dependencies = [ "logos-codegen", ] [[package]] name = "lru" -version = "0.12.5" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.1", ] [[package]] name = "md5" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" +checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0" [[package]] name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "memoffset" -version = "0.9.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "mimalloc-sys" @@ -785,6 +801,15 @@ ] [[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -792,11 +817,35 @@ [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] [[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] name = "pathdiff" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -840,27 +889,41 @@ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + +[[package]] name = "psm" -version = "0.1.26" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" +checksum = "3852766467df634d74f0b2d7819bf8dc483a0eb2e3b0f50f756f9cfe8b0d18d8" dependencies = [ + "ar_archive_writer", "cc", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -873,20 +936,19 @@ [[package]] name = "rand" -version = "0.8.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", "rand_core", @@ -894,18 +956,18 @@ [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.2.16", + "getrandom", ] [[package]] name = "random_color" -version = "0.8.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0085421bc527effa7ed6d46bac0a28734663c47abe03d80a5e78e441fad85196" +checksum = "d635c5e80ae160390ac62ca027d2d06c94c1dc69e5c0a12f1e3a53664dc84966" dependencies = [ "rand", ] @@ -921,9 +983,9 @@ [[package]] name = "regex" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -933,9 +995,9 @@ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -944,20 +1006,19 @@ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "rowan" -version = "0.15.17" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4f1e4a001f863f41ea8d0e6a0c34b356d5b733db50dadab3efef640bafb779b" +checksum = "417a3a9f582e349834051b8a10c8d71ca88da4211e4093528e36b9845f6b5f21" dependencies = [ "countme", "hashbrown 0.14.5", - "memoffset", - "rustc-hash", + "rustc-hash 1.1.0", "text-size", ] @@ -968,38 +1029,60 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] name = "rustix" -version = "1.0.8" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] [[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1008,26 +1091,29 @@ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ + "indexmap", "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] name = "serde_yaml_with_quirks" -version = "0.8.24" +version = "0.9.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c5983eba86eae2d0058c35fb1065ccffb23af7f8965871069269088098321a" +checksum = "d852180e55e824bb347a8e3cdbbca1f02513ea1fa00188f1b2a8a255ac3d6cf9" dependencies = [ - "indexmap 1.9.3", + "indexmap", + "itoa", "ryu", "serde", - "yaml-rust", + "unsafe-libyaml", ] [[package]] @@ -1082,9 +1168,9 @@ [[package]] name = "stacker" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b" +checksum = "08d74a23609d509411d10e2176dc2a4346e3b4aea2e7b1869f19fdedbc71c013" dependencies = [ "cc", "cfg-if", @@ -1100,6 +1186,18 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] +name = "str_indices" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" + +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + +[[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1107,9 +1205,9 @@ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -1129,15 +1227,15 @@ [[package]] name = "tempfile" -version = "3.21.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1160,18 +1258,18 @@ [[package]] name = "thiserror" -version = "1.0.69" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.69" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -1179,10 +1277,42 @@ ] [[package]] +name = "tree-sitter" +version = "0.26.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12987371f54efc9b9306a20dc87ed5aaee9f320c8a8b115e28515c412b2efe39" +dependencies = [ + "cc", + "regex", + "regex-syntax", + "serde_json", + "streaming-iterator", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-highlight" +version = "0.26.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b688407049ea1b55a7e872f138947d22389118b9c4d09b459cb34ca205e41c0" +dependencies = [ + "regex", + "streaming-iterator", + "thiserror", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-language" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" + +[[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ungrammar" @@ -1191,16 +1321,28 @@ checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f" [[package]] +name = "unicode-box-drawing" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1f97719cf40224391201fc11e7f5b0cc0ba21416367cfc914e2d45af4e42ef" + +[[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "utf8parse" @@ -1215,25 +1357,19 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -1241,16 +1377,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.3", + "windows-link", ] [[package]] @@ -1259,31 +1395,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -1293,58 +1412,28 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -1353,43 +1442,22 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "xshell" @@ -1412,7 +1480,7 @@ dependencies = [ "anyhow", "clap", - "indexmap 2.10.0", + "indexmap", "itertools", "proc-macro2", "quote", @@ -1421,30 +1489,33 @@ ] [[package]] -name = "yaml-rust" -version = "0.4.5" +name = "yansi" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ jrsonnet-stdlib = { path = "./crates/jrsonnet-stdlib", version = "0.5.0-pre97" } jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre97" } jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre97" } -jrsonnet-gcmodule = { version = "0.3.7" } +jrsonnet-gcmodule = { version = "0.4.0", path = "../gcmodule" } # Diagnostics. # hi-doc is my library, which handles text formatting very well, but isn't polished enough yet # Previous implementation was based on annotate-snippets, which I don't like for many reasons. @@ -27,8 +27,8 @@ # I'm against using miette, because I want to reuse data between interpreter and annotations, yet miette # and other libraries want to handle spans etc by itself, which is okay for compiler diagnostics, but is # bad for interpreter, where interpreter and parser are paired much closer. -hi-doc = "0.1.1" -annotate-snippets = "0.10.1" +hi-doc = "0.3.0" +annotate-snippets = "0.12.11" # CLI clap = "4.5" @@ -37,57 +37,57 @@ # Parsing, manifestification is implemented manually everywhere # Note on serde_yaml_with_quirks: This is a fork of serde-yaml with legacy yaml 1.1 support: # https://github.com/dtolnay/serde-yaml/pull/225 -serde = "1.0.197" -serde_json = "1.0.114" -serde_yaml_with_quirks = "0.8.24" +serde = "1.0.228" +serde_json = "1.0.149" +serde_yaml_with_quirks = "0.9.34" # Error handling -anyhow = "1.0.83" -thiserror = "1.0.60" +anyhow = "1.0.101" +thiserror = "2.0.18" # Code formatting -dprint-core = "0.65.0" +dprint-core = "0.67.4" # Stdlib hashing functions -md5 = "0.7.0" +md5 = "0.8.0" sha1 = "0.10.6" -sha2 = "0.10.8" +sha2 = "0.10.9" sha3 = "0.10.8" # Source code parsing. # Jrsonnet has two parsers for jsonnet - one is for execution, and another is for better parsing diagnostics/lints/LSP. # First (and fast one) is based on peg, second is based on rowan. -peg = "0.8.3" -logos = "0.14.0" +peg = "0.8.5" +logos = "0.16.1" ungrammar = "1.16.1" -rowan = "0.15.15" +rowan = "0.16.1" mimallocator = "0.1.3" indoc = "2.0" -insta = "1.39" -tempfile = "3.10" -pathdiff = "0.2.1" -hashbrown = "0.14.5" +insta = "1.46" +tempfile = "3.24" +pathdiff = "0.2.3" +hashbrown = "0.16.1" static_assertions = "1.1" -rustc-hash = "1.1" -num-bigint = "0.4.5" -strsim = "0.11.0" +rustc-hash = "2.1" +num-bigint = "0.4.6" +strsim = "0.11.1" proc-macro2 = "1.0" quote = "1.0" syn = "2.0" drop_bomb = "0.1.5" base64 = "0.22.1" -indexmap = "2.2.3" -itertools = "0.13.0" -xshell = "0.2.6" +indexmap = "2.13.0" +itertools = "0.14.0" +xshell = "0.2.7" -lsp-server = "0.7.6" -lsp-types = "0.96.0" +lsp-server = "0.7.9" +lsp-types = "0.97.0" -regex = "1.10" -lru = "0.12.3" +regex = "1.12" +lru = "0.16.3" -json-structural-diff = "0.1.0" +json-structural-diff = "0.2.0" syn-dissect-closure = "0.1.0" [workspace.lints.rust] --- a/bindings/jsonnet/Cargo.toml +++ b/bindings/jsonnet/Cargo.toml @@ -39,5 +39,5 @@ interop-threading = [] experimental = ["exp-preserve-order", "exp-destruct"] -exp-preserve-order = ["jrsonnet-evaluator/exp-preserve-order"] +exp-preserve-order = ["jrsonnet-evaluator/exp-preserve-order", "jrsonnet-stdlib/exp-preserve-order"] exp-destruct = ["jrsonnet-evaluator/exp-destruct"] --- a/bindings/jsonnet/src/import.rs +++ b/bindings/jsonnet/src/import.rs @@ -2,7 +2,6 @@ use std::{ alloc::Layout, - any::Any, cell::RefCell, collections::HashMap, env::current_dir, @@ -17,7 +16,7 @@ error::{ErrorKind::*, Result}, ImportResolver, }; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_parser::{SourceDirectory, SourceFile, SourcePath}; use crate::VM; @@ -32,11 +31,9 @@ ) -> c_int; /// Resolves imports using callback -#[derive(Trace)] +#[derive(Acyclic)] pub struct CallbackImportResolver { - #[trace(skip)] cb: JsonnetImportCallback, - #[trace(skip)] ctx: *mut c_void, out: RefCell>>, } @@ -101,14 +98,6 @@ } fn load_file_contents(&self, resolved: &SourcePath) -> Result> { Ok(self.out.borrow().get(resolved).unwrap().clone()) - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self } } --- a/bindings/jsonnet/src/interop.rs +++ b/bindings/jsonnet/src/interop.rs @@ -60,7 +60,7 @@ #[cfg(feature = "interop-common")] mod common { - use jrsonnet_evaluator::trace::{CompactFormat, ExplainingFormat, JsFormat, PathResolver}; + use jrsonnet_evaluator::trace::{CompactFormat, HiDocFormat, JsFormat, PathResolver}; use crate::VM; @@ -76,7 +76,7 @@ } 1 => vm.trace_format = Box::new(JsFormat { max_trace: 20 }), 2 => { - vm.trace_format = Box::new(ExplainingFormat { + vm.trace_format = Box::new(HiDocFormat { resolver: PathResolver::new_cwd_fallback(), max_trace: 20, }); --- a/bindings/jsonnet/src/lib.rs +++ b/bindings/jsonnet/src/lib.rs @@ -17,19 +17,20 @@ ffi::{CStr, CString, OsStr}, os::raw::{c_char, c_double, c_int, c_uint}, path::{Path, PathBuf}, + rc::Rc, }; use jrsonnet_evaluator::{ apply_tla, bail, function::TlaArg, - gc::{GcHashMap, TraceBox}, + gc::WithCapacityExt as _, manifest::{JsonFormat, ManifestFormat, ToStringFormat}, + rustc_hash::FxHashMap, stack::set_stack_depth_limit, - tb, trace::{CompactFormat, PathResolver, TraceFormat}, FileImportResolver, IStr, ImportResolver, Result, State, Val, }; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_parser::SourcePath; use jrsonnet_stdlib::ContextInitializer; @@ -47,7 +48,7 @@ b"v0.20.0\0" } -unsafe fn parse_path(input: &CStr) -> Cow { +unsafe fn parse_path(input: &CStr) -> Cow<'_, Path> { #[cfg(target_family = "unix")] { use std::os::unix::ffi::OsStrExt; @@ -61,7 +62,7 @@ } } -unsafe fn unparse_path(input: &Path) -> Cow { +unsafe fn unparse_path(input: &Path) -> Cow<'_, CStr> { #[cfg(target_family = "unix")] { use std::os::unix::ffi::OsStrExt; @@ -76,15 +77,14 @@ } } -#[derive(Trace)] +#[derive(Acyclic)] struct VMImportResolver { - #[trace(tracking(force))] - inner: RefCell>, + inner: RefCell>, } impl VMImportResolver { fn new(value: impl ImportResolver) -> Self { Self { - inner: RefCell::new(tb!(value)), + inner: RefCell::new(Rc::new(value)), } } } @@ -103,13 +103,6 @@ fn resolve(&self, path: &Path) -> Result { self.inner.borrow().resolve(path) - } - - fn as_any(&self) -> &dyn Any { - self - } - fn as_any_mut(&mut self) -> &mut dyn Any { - self } } @@ -117,28 +110,23 @@ state: State, manifest_format: Box, trace_format: Box, - tla_args: GcHashMap, + tla_args: FxHashMap, } impl VM { fn replace_import_resolver(&self, resolver: impl ImportResolver) { - *self - .state - .import_resolver() - .as_any() + *(self.state.import_resolver() as &dyn Any) .downcast_ref::() .expect("valid resolver ty") .inner - .borrow_mut() = tb!(resolver); + .borrow_mut() = Rc::new(resolver); } fn add_jpath(&self, path: PathBuf) { - self.state - .import_resolver() - .as_any() + let ir = self.state.import_resolver(); + let vmi = (ir as &dyn Any) .downcast_ref::() - .expect("valid resolver ty") - .inner - .borrow_mut() - .as_any_mut() + .expect("valid resolver ty"); + let vmi = &mut *vmi.inner.borrow_mut(); + (vmi as &mut dyn Any) .downcast_mut::() .expect("jpaths are not compatible with callback imports!") .add_jpath(path); @@ -158,7 +146,7 @@ state, manifest_format: Box::new(JsonFormat::default()), trace_format: Box::new(CompactFormat::default()), - tla_args: GcHashMap::new(), + tla_args: FxHashMap::new(), })) } --- a/cmds/jrsonnet-fmt/src/main.rs +++ b/cmds/jrsonnet-fmt/src/main.rs @@ -46,7 +46,7 @@ o }}; (@s; $o:ident: str($e:expr $(,)?) $($t:tt)*) => {{ - $o.push_str($e); + $o.push_string($e.to_owned()); pi!(@s; $o: $($t)*); }}; (@s; $o:ident: string($e:expr $(,)?) $($t:tt)*) => {{ @@ -711,8 +711,8 @@ let mut builder = hi_doc::SnippetBuilder::new(input); for error in errors { builder - .error(hi_doc::Text::single( - format!("{:?}", error.error).chars(), + .error(hi_doc::Text::fragment( + format!("{:?}", error.error), Formatting::default(), )) .range( --- a/cmds/jrsonnet/Cargo.toml +++ b/cmds/jrsonnet/Cargo.toml @@ -44,8 +44,6 @@ # --exp-apply exp-apply = [] -nightly = ["jrsonnet-evaluator/nightly"] - [dependencies] jrsonnet-evaluator.workspace = true jrsonnet-parser.workspace = true --- a/crates/jrsonnet-cli/src/tla.rs +++ b/crates/jrsonnet-cli/src/tla.rs @@ -2,7 +2,8 @@ use jrsonnet_evaluator::{ error::{ErrorKind, Result}, function::TlaArg, - gc::GcHashMap, + gc::WithCapacityExt as _, + rustc_hash::FxHashMap, IStr, }; use jrsonnet_parser::{ParserSettings, Source}; @@ -32,8 +33,8 @@ tla_code_file: Vec, } impl TlaOpts { - pub fn tla_opts(&self) -> Result> { - let mut out = GcHashMap::new(); + pub fn tla_opts(&self) -> Result> { + let mut out = FxHashMap::new(); for (name, value) in self .tla_str .iter() --- a/crates/jrsonnet-cli/src/trace.rs +++ b/crates/jrsonnet-cli/src/trace.rs @@ -1,7 +1,5 @@ use clap::{Parser, ValueEnum}; -use jrsonnet_evaluator::trace::{ - CompactFormat, ExplainingFormat, HiDocFormat, PathResolver, TraceFormat, -}; +use jrsonnet_evaluator::trace::{CompactFormat, HiDocFormat, PathResolver, TraceFormat}; #[derive(PartialEq, Eq, ValueEnum, Clone)] pub enum TraceFormatName { @@ -9,7 +7,7 @@ Compact, /// Display source code with attached trace annotations Explaining, - /// Experimental trace formatting based on hi-doc library + /// Trace formatting based on hi-doc library HiDoc, } @@ -38,11 +36,7 @@ padding: 4, max_trace, }), - TraceFormatName::Explaining => Box::new(ExplainingFormat { - resolver, - max_trace, - }), - TraceFormatName::HiDoc => Box::new(HiDocFormat { + TraceFormatName::Explaining | TraceFormatName::HiDoc => Box::new(HiDocFormat { resolver, max_trace, }), --- a/crates/jrsonnet-evaluator/Cargo.toml +++ b/crates/jrsonnet-evaluator/Cargo.toml @@ -7,6 +7,8 @@ repository.workspace = true version.workspace = true +build = "build.rs" + [lints] workspace = true @@ -16,8 +18,6 @@ explaining-traces = ["annotate-snippets", "hi-doc"] # Allows library authors to throw custom errors anyhow-error = ["anyhow"] -# Adds ability to build import closure in async -async-import = [] # Allows to preserve field order in objects exp-preserve-order = [] @@ -29,9 +29,6 @@ exp-bigint = ["num-bigint", "jrsonnet-types/exp-bigint"] # obj?.field, obj?.['field'] exp-null-coaelse = ["jrsonnet-parser/exp-null-coaelse"] - -# Improves performance, and implements some useful things using nightly-only features -nightly = ["hashbrown/nightly"] [dependencies] jrsonnet-interner.workspace = true @@ -41,7 +38,6 @@ jrsonnet-gcmodule.workspace = true pathdiff.workspace = true -hashbrown.workspace = true static_assertions.workspace = true rustc-hash.workspace = true @@ -59,4 +55,8 @@ hi-doc = { workspace = true, optional = true } # Bigint num-bigint = { workspace = true, features = ["serde"], optional = true } -stacker = "0.1.15" + +stacker = "0.1.23" + +[build-dependencies] +rustversion = "1.0.22" --- /dev/null +++ b/crates/jrsonnet-evaluator/build.rs @@ -0,0 +1,6 @@ +fn main() { + println!("cargo:rustc-check-cfg=cfg(nightly)"); + if rustversion::cfg!(nightly) { + println!("cargo:rustc-cfg=nightly"); + } +} --- a/crates/jrsonnet-evaluator/src/arr/mod.rs +++ b/crates/jrsonnet-evaluator/src/arr/mod.rs @@ -1,19 +1,30 @@ -use std::{any::Any, num::NonZeroU32}; +use std::{ + any::Any, + fmt::{self}, + num::NonZeroU32, +}; -use jrsonnet_gcmodule::{Cc, Trace}; +use jrsonnet_gcmodule::{cc_dyn, Cc}; use jrsonnet_interner::IBytes; use jrsonnet_parser::LocExpr; -use crate::{function::FuncVal, gc::TraceBox, tb, Context, Result, Thunk, Val}; +use crate::{function::FuncVal, Context, Result, Thunk, Val}; mod spec; pub use spec::{ArrayLike, *}; -/// Represents a Jsonnet array value. -#[derive(Debug, Clone, Trace)] -// may contain other ArrValue -#[trace(tracking(force))] -pub struct ArrValue(Cc>); +cc_dyn!( + #[doc = "Represents a Jsonnet array value."] + #[derive(Clone)] + ArrValue, + ArrayLike, + pub fn new() {...} +); +impl fmt::Debug for ArrValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} pub trait ArrayLikeIter: Iterator + DoubleEndedIterator + ExactSizeIterator {} impl ArrayLikeIter for I where @@ -22,9 +33,6 @@ } impl ArrValue { - pub fn new(v: impl ArrayLike) -> Self { - Self(Cc::new(tb!(v))) - } pub fn empty() -> Self { Self::new(RangeArray::empty()) } @@ -232,6 +240,3 @@ self.0.is_cheap() } } - -#[cfg(target_pointer_width = "64")] -static_assertions::assert_eq_size!(ArrValue, [u8; 8]); --- a/crates/jrsonnet-evaluator/src/async_import.rs +++ b/crates/jrsonnet-evaluator/src/async_import.rs @@ -1,14 +1,15 @@ -use std::{cell::RefCell, future::Future, path::Path}; +use std::{any::Any, cell::RefCell, future::Future, path::Path}; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_interner::IStr; use jrsonnet_parser::{ ArgsDesc, AssertStmt, BindSpec, CompSpec, Destruct, Expr, FieldMember, FieldName, ForSpecData, IfSpecData, LocExpr, Member, ObjBody, Param, ParamsDesc, ParserSettings, SliceDesc, Source, SourcePath, }; +use rustc_hash::FxHashMap; -use crate::{bail, gc::GcHashMap, FileData, ImportResolver, State}; +use crate::{bail, FileData, ImportResolver, State}; pub struct Import { path: IStr, @@ -132,12 +133,12 @@ ObjBody::ObjComp(_) => todo!(), } } - match &*expr.0 { + match &*expr.expr() { Expr::Import(v) | Expr::ImportStr(v) | Expr::ImportBin(v) => { - if let Expr::Str(s) = &*v.0 { + if let Expr::Str(s) = &*v.expr() { out.0.push(Import { path: s.clone(), - expression: matches!(&*expr.0, Expr::Import(_)), + expression: matches!(&*expr.expr(), Expr::Import(_)), }); } // Non-string import will fail in runtime @@ -250,9 +251,9 @@ ) -> impl Future, Self::Error>>; } -#[derive(Trace)] +#[derive(Acyclic)] struct ResolvedImportResolver { - resolved: RefCell>, + resolved: RefCell>, } impl ImportResolver for ResolvedImportResolver { fn load_file_contents(&self, _resolved: &SourcePath) -> crate::Result> { @@ -278,10 +279,6 @@ path.to_owned() )) } - - fn as_any(&self) -> &dyn std::any::Any { - self - } } enum Job { @@ -295,13 +292,12 @@ where H: AsyncImportResolver, { - let mut resolved = s - .import_resolver() - .as_any() + let resolved = (s.import_resolver() as &dyn Any) .downcast_ref::() - .map_or_else(GcHashMap::new, |resolver| { - std::mem::take(&mut *resolver.resolved.borrow_mut()) - }); + .expect("for async imports, import_resolver should be set to ResolvedImportResolver"); + + let mut resolved_map = resolved.resolved.borrow_mut(); + let mut queue = vec![Job::LoadFile { path: handler.resolve(path.as_ref()).await?, parse: true, @@ -344,7 +340,7 @@ } Job::ResolveImport { from, import } => { if let Some((resolved, expression)) = - resolved.get_mut(&(from.clone(), import.path.clone())) + resolved_map.get_mut(&(from.clone(), import.path.clone())) { if import.expression && !*expression { *expression = true; @@ -360,8 +356,5 @@ } } } - s.set_import_resolver(ResolvedImportResolver { - resolved: RefCell::new(resolved), - }); Ok(()) } --- a/crates/jrsonnet-evaluator/src/ctx.rs +++ b/crates/jrsonnet-evaluator/src/ctx.rs @@ -2,10 +2,11 @@ use jrsonnet_gcmodule::{Cc, Trace}; use jrsonnet_interner::IStr; +use rustc_hash::FxHashMap; use crate::{ - error::ErrorKind::*, gc::GcHashMap, map::LayeredHashMap, ObjValue, Pending, Result, State, - Thunk, Val, + error::ErrorKind::*, gc::WithCapacityExt as _, map::LayeredHashMap, ObjValue, Pending, Result, + State, Thunk, Val, }; #[derive(Trace)] @@ -88,7 +89,7 @@ #[must_use] pub fn with_var(self, name: impl Into, value: Val) -> Self { - let mut new_bindings = GcHashMap::with_capacity(1); + let mut new_bindings = FxHashMap::with_capacity(1); new_bindings.insert(name.into(), Thunk::evaluated(value)); self.extend(new_bindings, None, None, None) } @@ -96,7 +97,7 @@ #[must_use] pub fn extend( self, - new_bindings: GcHashMap>, + new_bindings: FxHashMap>, new_dollar: Option, new_sup: Option, new_this: Option, @@ -128,7 +129,7 @@ pub struct ContextBuilder { state: Option, - bindings: GcHashMap>, + bindings: FxHashMap>, extend: Option, } @@ -138,7 +139,7 @@ pub fn dangerous_empty_state() -> Self { Self { state: None, - bindings: GcHashMap::new(), + bindings: FxHashMap::new(), extend: None, } } @@ -148,14 +149,14 @@ pub fn with_capacity(state: State, capacity: usize) -> Self { Self { state: Some(state), - bindings: GcHashMap::with_capacity(capacity), + bindings: FxHashMap::with_capacity(capacity), extend: None, } } pub fn extend(parent: Context) -> Self { Self { state: parent.0.state.clone(), - bindings: GcHashMap::new(), + bindings: FxHashMap::new(), extend: Some(parent), } } --- a/crates/jrsonnet-evaluator/src/error.rs +++ b/crates/jrsonnet-evaluator/src/error.rs @@ -138,12 +138,12 @@ #[error("assert failed: {}", format_empty_str(.0))] AssertionFailed(IStr), - #[error("local is not defined: {0}{}", format_found(.1, "local"))] + #[error("local is not defined: {0}{found}", found = format_found(.1, "local"))] VariableIsNotDefined(IStr, Vec), #[error("duplicate local var: {0}")] DuplicateLocalVar(IStr), - #[error("type mismatch: expected {}, got {2} {0}", .1.iter().map(|e| format!("{e}")).collect::>().join(", "))] + #[error("type mismatch: expected {expected}, got {2} {0}", expected = .1.iter().map(|e| format!("{e}")).collect::>().join(", "))] TypeMismatch(&'static str, Vec, ValType), #[error("no such field: {}{}", format_empty_str(.0), format_found(.1, "field"))] NoSuchField(IStr, Vec), @@ -154,7 +154,7 @@ UnknownFunctionParameter(String), #[error("argument {0} is already bound")] BindingParameterASecondTime(IStr), - #[error("too many args, function has {0}{}", format_signature(.1))] + #[error("too many args, function has {0}{sig}", sig = format_signature(.1))] TooManyArgsFunctionHas(usize, FunctionSignature), #[error("function argument is not passed: {}{}", .0.as_ref().map_or("", IStr::as_str), format_signature(.1))] FunctionParameterNotBoundInCall(Option, FunctionSignature), --- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs @@ -1,12 +1,11 @@ use jrsonnet_interner::IStr; use jrsonnet_parser::{BindSpec, Destruct}; +use rustc_hash::FxHashMap; use crate::{ bail, error::{ErrorKind::*, Result}, - evaluate, evaluate_method, evaluate_named, - gc::GcHashMap, - Context, Pending, Thunk, Val, + evaluate, evaluate_method, evaluate_named, Context, Pending, Thunk, Val, }; #[allow(clippy::too_many_lines)] @@ -15,7 +14,7 @@ d: &Destruct, parent: Thunk, fctx: Pending, - new_bindings: &mut GcHashMap>, + new_bindings: &mut FxHashMap>, ) -> Result<()> { match d { Destruct::Full(v) => { @@ -163,7 +162,7 @@ pub fn evaluate_dest( d: &BindSpec, fctx: Pending, - new_bindings: &mut GcHashMap>, + new_bindings: &mut FxHashMap>, ) -> Result<()> { match d { BindSpec::Field { into, value } => { --- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs @@ -7,6 +7,7 @@ ForSpecData, IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, }; use jrsonnet_types::ValType; +use rustc_hash::FxHashMap; use self::destructure::destruct; use crate::{ @@ -16,11 +17,12 @@ error::{suggest_object_fields, ErrorKind::*}, evaluate::operator::{evaluate_add_op, evaluate_binary_op_special, evaluate_unary_op}, function::{CallLocation, FuncDesc, FuncVal}, + gc::WithCapacityExt as _, in_frame, typed::Typed, val::{CachedUnbound, IndexableVal, NumValue, StrValue, Thunk}, - Context, Error, GcHashMap, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result, - ResultExt, Unbound, Val, + Context, Error, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result, ResultExt, + Unbound, Val, }; pub mod destructure; pub mod operator; @@ -122,7 +124,7 @@ Val::Arr(list) => { for item in list.iter_lazy() { let fctx = Pending::new(); - let mut new_bindings = GcHashMap::with_capacity(var.capacity_hint()); + let mut new_bindings = FxHashMap::with_capacity(var.capacity_hint()); destruct(var, item, fctx.clone(), &mut new_bindings)?; let ctx = ctx .clone() @@ -140,7 +142,7 @@ false, ) { let fctx = Pending::new(); - let mut new_bindings = GcHashMap::with_capacity(var.capacity_hint()); + let mut new_bindings = FxHashMap::with_capacity(var.capacity_hint()); let obj = obj.clone(); let value = Thunk::evaluated(Val::Arr(ArrValue::lazy(vec![ Thunk::evaluated(Val::string(field.clone())), @@ -181,7 +183,7 @@ fn bind(&self, sup: Option, this: Option) -> Result { let fctx = Context::new_future(); let mut new_bindings = - GcHashMap::with_capacity(self.locals.iter().map(BindSpec::capacity_hint).sum()); + FxHashMap::with_capacity(self.locals.iter().map(BindSpec::capacity_hint).sum()); for b in self.locals.iter() { evaluate_dest(b, fctx.clone(), &mut new_bindings)?; } @@ -329,7 +331,7 @@ } } let this = builder.build(); - fctx.fill(ctx.extend(GcHashMap::new(), None, None, Some(this.clone()))); + fctx.fill(ctx.extend(FxHashMap::new(), None, None, Some(this.clone()))); Ok(this) } @@ -357,7 +359,7 @@ let this = builder.build(); for (ctx, fctx) in ctxs { let _ctx = ctx - .extend(GcHashMap::new(), None, None, Some(this.clone())) + .extend(FxHashMap::new(), None, None, Some(this.clone())) .into_future(fctx); } this @@ -581,8 +583,8 @@ Ok(indexable) })?, LocalExpr(bindings, returned) => { - let mut new_bindings: GcHashMap> = - GcHashMap::with_capacity(bindings.iter().map(BindSpec::capacity_hint).sum()); + let mut new_bindings: FxHashMap> = + FxHashMap::with_capacity(bindings.iter().map(BindSpec::capacity_hint).sum()); let fctx = Context::new_future(); for b in bindings { evaluate_dest(b, fctx.clone(), &mut new_bindings)?; --- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs @@ -2,11 +2,6 @@ use jrsonnet_parser::{BinaryOpType, LocExpr, UnaryOpType}; -#[cfg(feature = "exp-bigint")] -use num_traits::{FromPrimitive, ToPrimitive}; - -#[cfg(feature = "exp-bigint")] -use crate::val::NumValue; use crate::{ arr::ArrValue, bail, --- a/crates/jrsonnet-evaluator/src/function/arglike.rs +++ b/crates/jrsonnet-evaluator/src/function/arglike.rs @@ -1,9 +1,10 @@ -use hashbrown::HashMap; +use std::collections::HashMap; + use jrsonnet_gcmodule::Trace; use jrsonnet_interner::IStr; use jrsonnet_parser::{ArgsDesc, LocExpr}; -use crate::{evaluate, gc::GcHashMap, typed::Typed, Context, Result, Thunk, Val}; +use crate::{evaluate, typed::Typed, Context, Result, Thunk, Val}; /// Marker for arguments, which can be evaluated with context set to None pub trait OptionalContext {} @@ -204,38 +205,6 @@ } } impl OptionalContext for HashMap where V: ArgLike + OptionalContext {} - -impl ArgsLike for GcHashMap { - fn unnamed_len(&self) -> usize { - self.0.unnamed_len() - } - - fn unnamed_iter( - &self, - ctx: Context, - tailstrict: bool, - handler: &mut dyn FnMut(usize, Thunk) -> Result<()>, - ) -> Result<()> { - self.0.unnamed_iter(ctx, tailstrict, handler) - } - - fn named_iter( - &self, - ctx: Context, - tailstrict: bool, - handler: &mut dyn FnMut(&IStr, Thunk) -> Result<()>, - ) -> Result<()> { - self.0.named_iter(ctx, tailstrict, handler) - } - - fn named_names(&self, handler: &mut dyn FnMut(&IStr)) { - self.0.named_names(handler); - } - - fn is_empty(&self) -> bool { - self.0.is_empty() - } -} macro_rules! impl_args_like { ($count:expr; $($gen:ident)*) => { --- a/crates/jrsonnet-evaluator/src/function/builtin.rs +++ b/crates/jrsonnet-evaluator/src/function/builtin.rs @@ -1,10 +1,10 @@ use std::{any::Any, borrow::Cow}; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::{cc_dyn, Trace, TraceBox}; use jrsonnet_interner::IStr; use super::{arglike::ArgsLike, parse::parse_builtin_call, CallLocation}; -use crate::{gc::TraceBox, tb, Context, Result, Val}; +use crate::{Context, Result, Val}; /// Can't have `str` | `IStr`, because constant `BuiltinParam` causes /// `E0492: constant functions cannot refer to interior mutable data` @@ -70,6 +70,30 @@ } } +cc_dyn!( + #[derive(Clone)] + BuiltinFunc, + Builtin, + pub(crate) fn new() {...} +); +impl Builtin for BuiltinFunc { + fn name(&self) -> &str { + self.0.name() + } + + fn params(&self) -> &[BuiltinParam] { + self.0.params() + } + + fn call(&self, ctx: Context, loc: CallLocation<'_>, args: &dyn ArgsLike) -> Result { + self.0.call(ctx, loc, args) + } + + fn as_any(&self) -> &dyn Any { + self.0.as_any() + } +} + /// Description of function defined by native code /// /// Prefer to use #[builtin] macro, instead of manual implementation of this trait @@ -108,7 +132,7 @@ default: ParamDefault::None, }) .collect(), - handler: tb!(handler), + handler: TraceBox(Box::new(handler)), } } } --- a/crates/jrsonnet-evaluator/src/function/mod.rs +++ b/crates/jrsonnet-evaluator/src/function/mod.rs @@ -13,7 +13,7 @@ parse::{parse_default_function_call, parse_function_call}, }; use crate::{ - bail, error::ErrorKind::*, evaluate, evaluate_trivial, gc::TraceBox, tb, Context, + bail, error::ErrorKind::*, evaluate, evaluate_trivial, function::builtin::BuiltinFunc, Context, ContextBuilder, Result, Thunk, Val, }; @@ -102,7 +102,7 @@ /// Standard library function. StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin), /// User-provided function. - Builtin(Cc>), + Builtin(BuiltinFunc), } impl Debug for FuncVal { @@ -128,7 +128,7 @@ impl FuncVal { pub fn builtin(builtin: impl Builtin) -> Self { - Self::Builtin(Cc::new(tb!(builtin))) + Self::Builtin(BuiltinFunc::new(builtin)) } pub fn static_builtin(static_builtin: &'static dyn StaticBuiltin) -> Self { Self::StaticBuiltin(static_builtin) --- a/crates/jrsonnet-evaluator/src/function/parse.rs +++ b/crates/jrsonnet-evaluator/src/function/parse.rs @@ -2,6 +2,7 @@ use jrsonnet_interner::IStr; use jrsonnet_parser::ParamsDesc; +use rustc_hash::FxHashMap; use super::{arglike::ArgsLike, builtin::BuiltinParam}; use crate::{ @@ -10,7 +11,7 @@ error::{ErrorKind::*, Result}, evaluate_named, function::builtin::ParamDefault, - gc::GcHashMap, + gc::WithCapacityExt as _, Context, Pending, Thunk, Val, }; @@ -30,7 +31,7 @@ tailstrict: bool, ) -> Result { let mut passed_args = - GcHashMap::with_capacity(params.iter().map(|p| p.0.capacity_hint()).sum()); + FxHashMap::with_capacity(params.iter().map(|p| p.0.capacity_hint()).sum()); if args.unnamed_len() > params.len() { bail!(TooManyArgsFunctionHas( params.len(), @@ -72,7 +73,7 @@ // Some args are unset, but maybe we have defaults for them // Default values should be created in newly created context let fctx = Context::new_future(); - let mut defaults = GcHashMap::with_capacity( + let mut defaults = FxHashMap::with_capacity( params.iter().map(|p| p.0.capacity_hint()).sum::() - filled_named - filled_positionals, @@ -220,7 +221,7 @@ pub fn parse_default_function_call(body_ctx: Context, params: &ParamsDesc) -> Result { let fctx = Context::new_future(); - let mut bindings = GcHashMap::with_capacity(params.iter().map(|p| p.0.capacity_hint()).sum()); + let mut bindings = FxHashMap::with_capacity(params.iter().map(|p| p.0.capacity_hint()).sum()); for param in params.iter() { if let Some(v) = ¶m.1 { --- a/crates/jrsonnet-evaluator/src/gc.rs +++ b/crates/jrsonnet-evaluator/src/gc.rs @@ -1,161 +1,27 @@ /// Macros to help deal with Gc -use std::{ - borrow::{Borrow, BorrowMut}, - collections::HashSet, - hash::BuildHasherDefault, - ops::{Deref, DerefMut}, -}; - -use hashbrown::HashMap; -use jrsonnet_gcmodule::{Trace, Tracer}; -use rustc_hash::{FxHashSet, FxHasher}; +use jrsonnet_gcmodule::Trace; +use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; -/// Replacement for box, which assumes that the underlying type is [`Trace`] -/// Used in places, where `Cc` should be used instead, but it can't, because `CoerceUnsiced` is not stable -#[derive(Debug, Clone)] -pub struct TraceBox(pub Box); -#[macro_export] -macro_rules! tb { - ($v:expr) => { - $crate::gc::TraceBox(Box::new($v)) - }; +pub trait WithCapacityExt { + fn new() -> Self; + fn with_capacity(capacity: usize) -> Self; } - -impl Trace for TraceBox { - fn trace(&self, tracer: &mut Tracer<'_>) { - self.0.trace(tracer); +impl WithCapacityExt for FxHashSet { + fn with_capacity(capacity: usize) -> Self { + Self::with_capacity_and_hasher(capacity, FxBuildHasher::default()) } - fn is_type_tracked() -> bool { - true + fn new() -> Self { + Self::with_hasher(FxBuildHasher::default()) } } - -// TODO: Replace with CoerceUnsized -impl From> for TraceBox { - fn from(inner: Box) -> Self { - Self(inner) +impl WithCapacityExt for FxHashMap { + fn with_capacity(capacity: usize) -> Self { + Self::with_capacity_and_hasher(capacity, FxBuildHasher::default()) } -} - -impl Deref for TraceBox { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl DerefMut for TraceBox { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl Borrow for TraceBox { - fn borrow(&self) -> &T { - &self.0 - } -} - -impl BorrowMut for TraceBox { - fn borrow_mut(&mut self) -> &mut T { - &mut self.0 - } -} - -impl AsRef for TraceBox { - fn as_ref(&self) -> &T { - &self.0 - } -} - -impl AsMut for TraceBox { - fn as_mut(&mut self) -> &mut T { - &mut self.0 - } -} - -#[derive(Clone)] -pub struct GcHashSet(pub FxHashSet); -impl GcHashSet { - pub fn new() -> Self { - Self(HashSet::default()) - } - pub fn with_capacity(capacity: usize) -> Self { - Self(FxHashSet::with_capacity_and_hasher( - capacity, - BuildHasherDefault::default(), - )) - } -} -impl Trace for GcHashSet -where - V: Trace, -{ - fn trace(&self, tracer: &mut Tracer<'_>) { - for v in &self.0 { - v.trace(tracer); - } - } -} -impl Deref for GcHashSet { - type Target = FxHashSet; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl DerefMut for GcHashSet { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} -impl Default for GcHashSet { - fn default() -> Self { - Self::new() - } -} - -#[derive(Debug)] -pub struct GcHashMap(pub HashMap>); -impl GcHashMap { - pub fn new() -> Self { - Self(HashMap::default()) - } - pub fn with_capacity(capacity: usize) -> Self { - Self(HashMap::with_capacity_and_hasher( - capacity, - BuildHasherDefault::default(), - )) - } -} -impl Trace for GcHashMap -where - K: Trace, - V: Trace, -{ - fn trace(&self, tracer: &mut Tracer<'_>) { - for (k, v) in &self.0 { - k.trace(tracer); - v.trace(tracer); - } - } -} -impl Deref for GcHashMap { - type Target = HashMap>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl DerefMut for GcHashMap { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} -impl Default for GcHashMap { - fn default() -> Self { - Self::new() + fn new() -> Self { + Self::with_hasher(FxBuildHasher::default()) } } --- a/crates/jrsonnet-evaluator/src/import.rs +++ b/crates/jrsonnet-evaluator/src/import.rs @@ -7,7 +7,7 @@ }; use fs::File; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_interner::IBytes; use jrsonnet_parser::{SourceDirectory, SourceFifo, SourceFile, SourcePath}; @@ -17,7 +17,7 @@ }; /// Implements file resolution logic for `import` and `importStr` -pub trait ImportResolver: Trace { +pub trait ImportResolver: Acyclic + Any { /// Resolves file path, e.g. `(/home/user/manifests, b.libjsonnet)` can correspond /// both to `/home/user/manifests/b.libjsonnet` and to `/home/user/${vendor}/b.libjsonnet` /// where `${vendor}` is a library path. @@ -39,26 +39,14 @@ /// This should only be called with value returned from [`ImportResolver::resolve_file`]/[`ImportResolver::resolve`], /// this cannot be resolved using associated type, as evaluator uses object instead of generic for [`ImportResolver`] fn load_file_contents(&self, resolved: &SourcePath) -> Result>; - - // For downcasts, will be removed after trait_upcasting_coercion - // stabilization. - fn as_any(&self) -> &dyn Any; - fn as_any_mut(&mut self) -> &mut dyn Any; } /// Dummy resolver, can't resolve/load any file -#[derive(Trace)] +#[derive(Acyclic)] pub struct DummyImportResolver; impl ImportResolver for DummyImportResolver { fn load_file_contents(&self, _resolved: &SourcePath) -> Result> { panic!("dummy resolver can't load any file") - } - - fn as_any(&self) -> &dyn Any { - self - } - fn as_any_mut(&mut self) -> &mut dyn Any { - self } } #[allow(clippy::use_self)] @@ -69,7 +57,7 @@ } /// File resolver, can load file from both FS and library paths -#[derive(Default, Trace)] +#[derive(Default, Acyclic)] pub struct FileImportResolver { /// Library directories to search for file. /// Referred to as `jpath` in original jsonnet implementation. @@ -169,13 +157,5 @@ fn resolve_from_default(&self, path: &str) -> Result { self.resolve_from(&SourcePath::default(), path) - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self } } --- a/crates/jrsonnet-evaluator/src/lib.rs +++ b/crates/jrsonnet-evaluator/src/lib.rs @@ -1,11 +1,10 @@ //! jsonnet interpreter implementation -#![cfg_attr(feature = "nightly", feature(thread_local, type_alias_impl_trait))] +#![cfg_attr(nightly, feature(thread_local, type_alias_impl_trait))] // For jrsonnet-macros extern crate self as jrsonnet_evaluator; mod arr; -#[cfg(feature = "async-import")] pub mod async_import; mod ctx; mod dynamic; @@ -28,8 +27,10 @@ use std::{ any::Any, cell::{RefCell, RefMut}, + collections::hash_map::Entry, fmt::{self, Debug}, path::Path, + rc::Rc, }; pub use ctx::*; @@ -37,20 +38,28 @@ pub use error::{Error, ErrorKind::*, Result, ResultExt}; pub use evaluate::*; use function::CallLocation; -use gc::{GcHashMap, TraceBox}; -use hashbrown::hash_map::RawEntryMut; pub use import::*; -use jrsonnet_gcmodule::{Cc, Trace}; +use jrsonnet_gcmodule::{cc_dyn, Cc, Trace}; pub use jrsonnet_interner::{IBytes, IStr}; #[doc(hidden)] pub use jrsonnet_macros; pub use jrsonnet_parser as parser; use jrsonnet_parser::{LocExpr, ParserSettings, Source, SourcePath}; pub use obj::*; +pub use rustc_hash; +use rustc_hash::FxHashMap; use stack::check_depth; pub use tla::apply_tla; pub use val::{Thunk, Val}; +use crate::gc::WithCapacityExt as _; + +cc_dyn!( + #[derive(Clone)] + CcUnbound, + Unbound +); + /// Thunk without bound `super`/`this` /// object inheritance may be overriden multiple times, and will be fixed only on field read pub trait Unbound: Trace { @@ -65,7 +74,7 @@ #[derive(Clone, Trace)] pub enum MaybeUnbound { /// Value needs to be bound to `this`/`super` - Unbound(Cc>>), + Unbound(CcUnbound), /// Value is object-independent Bound(Thunk), } @@ -79,12 +88,14 @@ /// Attach object context to value, if required pub fn evaluate(&self, sup: Option, this: Option) -> Result { match self { - Self::Unbound(v) => v.bind(sup, this), + Self::Unbound(v) => v.0.bind(sup, this), Self::Bound(v) => Ok(v.evaluate()?), } } } +cc_dyn!(CcContextInitializer, ContextInitializer); + /// During import, this trait will be called to create initial context for file. /// It may initialize global variables, stdlib for example. pub trait ContextInitializer: Trace { @@ -215,12 +226,12 @@ #[derive(Trace)] pub struct EvaluationStateInternals { /// Internal state - file_cache: RefCell>, + file_cache: RefCell>, /// Context initializer, which will be used for imports and everything /// [`NoopContextInitializer`] is used by default, most likely you want to have `jrsonnet-stdlib` - context_initializer: TraceBox, + context_initializer: CcContextInitializer, /// Used to resolve file locations/contents - import_resolver: TraceBox, + import_resolver: Rc, } /// Maintains stack trace and import resolution @@ -231,21 +242,17 @@ /// Should only be called with path retrieved from [`resolve_path`], may panic otherwise pub fn import_resolved_str(&self, path: SourcePath) -> Result { let mut file_cache = self.file_cache(); - let mut file = file_cache.raw_entry_mut().from_key(&path); + let mut file = file_cache.entry(path.clone()); let file = match file { - RawEntryMut::Occupied(ref mut d) => d.get_mut(), - RawEntryMut::Vacant(v) => { + Entry::Occupied(ref mut d) => d.get_mut(), + Entry::Vacant(v) => { let data = self.import_resolver().load_file_contents(&path)?; - v.insert( - path.clone(), - FileData::new_string( - std::str::from_utf8(&data) - .map_err(|_| ImportBadFileUtf8(path.clone()))? - .into(), - ), - ) - .1 + v.insert(FileData::new_string( + std::str::from_utf8(&data) + .map_err(|_| ImportBadFileUtf8(path.clone()))? + .into(), + )) } }; Ok(file @@ -255,14 +262,13 @@ /// Should only be called with path retrieved from [`resolve_path`], may panic otherwise pub fn import_resolved_bin(&self, path: SourcePath) -> Result { let mut file_cache = self.file_cache(); - let mut file = file_cache.raw_entry_mut().from_key(&path); + let mut file = file_cache.entry(path.clone()); let file = match file { - RawEntryMut::Occupied(ref mut d) => d.get_mut(), - RawEntryMut::Vacant(v) => { + Entry::Occupied(ref mut d) => d.get_mut(), + Entry::Vacant(v) => { let data = self.import_resolver().load_file_contents(&path)?; - v.insert(path.clone(), FileData::new_bytes(data.as_slice().into())) - .1 + v.insert(FileData::new_bytes(data.as_slice().into())) } }; if let Some(str) = &file.bytes { @@ -282,21 +288,17 @@ /// Should only be called with path retrieved from [`resolve_path`], may panic otherwise pub fn import_resolved(&self, path: SourcePath) -> Result { let mut file_cache = self.file_cache(); - let mut file = file_cache.raw_entry_mut().from_key(&path); + let mut file = file_cache.entry(path.clone()); let file = match file { - RawEntryMut::Occupied(ref mut d) => d.get_mut(), - RawEntryMut::Vacant(v) => { + Entry::Occupied(ref mut d) => d.get_mut(), + Entry::Vacant(v) => { let data = self.import_resolver().load_file_contents(&path)?; - v.insert( - path.clone(), - FileData::new_string( - std::str::from_utf8(&data) - .map_err(|_| ImportBadFileUtf8(path.clone()))? - .into(), - ), - ) - .1 + v.insert(FileData::new_string( + std::str::from_utf8(&data) + .map_err(|_| ImportBadFileUtf8(path.clone()))? + .into(), + )) } }; if let Some(val) = &file.evaluated { @@ -330,10 +332,10 @@ let res = evaluate(self.create_default_context(file_name), &parsed); let mut file_cache = self.file_cache(); - let mut file = file_cache.raw_entry_mut().from_key(&path); + let mut file = file_cache.entry(path.clone()); - let RawEntryMut::Occupied(file) = &mut file else { - unreachable!("this file was just here!") + let Entry::Occupied(file) = &mut file else { + unreachable!("this file was just here") }; let file = file.get_mut(); file.evaluating = false; @@ -381,7 +383,7 @@ /// Internals impl State { - fn file_cache(&self) -> RefMut<'_, GcHashMap> { + fn file_cache(&self) -> RefMut<'_, FxHashMap> { self.0.file_cache.borrow_mut() } } @@ -479,7 +481,7 @@ &*self.0.import_resolver } pub fn context_initializer(&self) -> &dyn ContextInitializer { - &*self.0.context_initializer + &*self.0.context_initializer.0 } } @@ -497,29 +499,34 @@ #[derive(Default)] pub struct StateBuilder { - import_resolver: Option>, - context_initializer: Option>, + import_resolver: Option>, + context_initializer: Option, } impl StateBuilder { pub fn import_resolver(&mut self, import_resolver: impl ImportResolver) -> &mut Self { - let _ = self.import_resolver.insert(tb!(import_resolver)); + let _ = self.import_resolver.insert(Rc::new(import_resolver)); self } pub fn context_initializer( &mut self, context_initializer: impl ContextInitializer, ) -> &mut Self { - let _ = self.context_initializer.insert(tb!(context_initializer)); + let _ = self + .context_initializer + .insert(CcContextInitializer::new(context_initializer)); self } pub fn build(mut self) -> State { State(Cc::new(EvaluationStateInternals { - file_cache: RefCell::new(GcHashMap::new()), - context_initializer: self.context_initializer.take().unwrap_or_else(|| tb!(())), + file_cache: RefCell::new(FxHashMap::new()), + context_initializer: self + .context_initializer + .take() + .unwrap_or_else(|| CcContextInitializer::new(())), import_resolver: self .import_resolver .take() - .unwrap_or_else(|| tb!(DummyImportResolver)), + .unwrap_or_else(|| Rc::new(DummyImportResolver)), })) } } --- a/crates/jrsonnet-evaluator/src/map.rs +++ b/crates/jrsonnet-evaluator/src/map.rs @@ -1,13 +1,14 @@ use jrsonnet_gcmodule::{Cc, Trace}; use jrsonnet_interner::IStr; +use rustc_hash::FxHashMap; -use crate::{GcHashMap, Thunk, Val}; +use crate::{gc::WithCapacityExt as _, Thunk, Val}; #[derive(Trace)] #[trace(tracking(force))] pub struct LayeredHashMapInternals { parent: Option, - current: GcHashMap>, + current: FxHashMap>, } #[derive(Trace)] @@ -15,7 +16,7 @@ impl LayeredHashMap { pub fn iter_keys(self, mut handler: impl FnMut(IStr)) { - for (k, _) in &*self.0.current { + for (k, _) in &self.0.current { handler(k.clone()); } if let Some(parent) = self.0.parent.clone() { @@ -23,14 +24,14 @@ } } - pub(crate) fn new(layer: GcHashMap>) -> Self { + pub(crate) fn new(layer: FxHashMap>) -> Self { Self(Cc::new(LayeredHashMapInternals { parent: None, current: layer, })) } - pub fn extend(self, new_layer: GcHashMap>) -> Self { + pub fn extend(self, new_layer: FxHashMap>) -> Self { Self(Cc::new(LayeredHashMapInternals { parent: Some(self), current: new_layer, @@ -64,7 +65,7 @@ fn default() -> Self { Self(Cc::new(LayeredHashMapInternals { parent: None, - current: GcHashMap::new(), + current: FxHashMap::new(), })) } } --- a/crates/jrsonnet-evaluator/src/obj.rs +++ b/crates/jrsonnet-evaluator/src/obj.rs @@ -6,22 +6,21 @@ ptr::addr_of, }; -use jrsonnet_gcmodule::{Cc, Trace, Weak}; +use jrsonnet_gcmodule::{cc_dyn, Cc, Trace, Weak}; use jrsonnet_interner::IStr; use jrsonnet_parser::{Span, Visibility}; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use crate::{ arr::{PickObjectKeyValues, PickObjectValues}, bail, error::{suggest_object_fields, Error, ErrorKind::*}, function::{CallLocation, FuncVal}, - gc::{GcHashMap, GcHashSet, TraceBox}, + gc::WithCapacityExt as _, in_frame, operator::evaluate_add_op, - tb, val::ArrValue, - MaybeUnbound, Result, Thunk, Unbound, Val, + CcUnbound, MaybeUnbound, Result, Thunk, Unbound, Val, }; #[cfg(not(feature = "exp-preserve-order"))] @@ -139,6 +138,7 @@ pub location: Option, } +cc_dyn!(CcObjectAssertion, ObjectAssertion); pub trait ObjectAssertion: Trace { fn run(&self, super_obj: Option, this: Option) -> Result<()>; } @@ -159,10 +159,10 @@ pub struct OopObject { sup: Option, // this: Option, - assertions: Cc>>, - assertions_ran: RefCell>, - this_entries: Cc>, - value_cache: RefCell), CacheValue>>, + assertions: Cc>, + assertions_ran: RefCell>, + this_entries: Cc>, + value_cache: RefCell), CacheValue>>, } impl Debug for OopObject { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -203,7 +203,7 @@ } #[derive(Clone, Trace)] -pub struct WeakObjValue(#[trace(skip)] pub(crate) Weak>); +pub struct WeakObjValue(#[trace(skip)] pub(crate) Weak); impl PartialEq for WeakObjValue { fn eq(&self, other: &Self) -> bool { @@ -220,9 +220,11 @@ } } -#[allow(clippy::module_name_repetitions)] -#[derive(Clone, Trace, Debug)] -pub struct ObjValue(pub(crate) Cc>); +cc_dyn!( + #[derive(Clone, Debug)] + ObjValue, ObjectLike, + pub fn new() {...} +); #[derive(Debug, Trace)] struct EmptyObject; @@ -331,9 +333,6 @@ } impl ObjValue { - pub fn new(v: impl ObjectLike) -> Self { - Self(Cc::new(tb!(v))) - } pub fn new_empty() -> Self { Self::new(EmptyObject) } @@ -582,16 +581,16 @@ impl OopObject { pub fn new( sup: Option, - this_entries: Cc>, - assertions: Cc>>, + this_entries: Cc>, + assertions: Cc>, ) -> Self { Self { sup, // this: None, assertions, - assertions_ran: RefCell::new(GcHashSet::new()), + assertions_ran: RefCell::new(FxHashSet::new()), this_entries, - value_cache: RefCell::new(GcHashMap::new()), + value_cache: RefCell::new(FxHashMap::new()), } } @@ -762,7 +761,7 @@ } if self.assertions_ran.borrow_mut().insert(real_this.clone()) { for assertion in self.assertions.iter() { - if let Err(e) = assertion.run(self.sup.clone(), Some(real_this.clone())) { + if let Err(e) = assertion.0.run(self.sup.clone(), Some(real_this.clone())) { self.assertions_ran.borrow_mut().remove(&real_this); return Err(e); } @@ -784,15 +783,15 @@ impl Eq for ObjValue {} impl Hash for ObjValue { fn hash(&self, hasher: &mut H) { - hasher.write_usize(addr_of!(*self.0) as usize); + hasher.write_usize(addr_of!(*self.0).expose_provenance() as usize); } } #[allow(clippy::module_name_repetitions)] pub struct ObjValueBuilder { sup: Option, - map: GcHashMap, - assertions: Vec>, + map: FxHashMap, + assertions: Vec, next_field_index: FieldIndex, } impl ObjValueBuilder { @@ -802,7 +801,7 @@ pub fn with_capacity(capacity: usize) -> Self { Self { sup: None, - map: GcHashMap::with_capacity(capacity), + map: FxHashMap::with_capacity(capacity), assertions: Vec::new(), next_field_index: FieldIndex::default(), } @@ -817,7 +816,7 @@ } pub fn assert(&mut self, assertion: impl ObjectAssertion + 'static) -> &mut Self { - self.assertions.push(tb!(assertion)); + self.assertions.push(CcObjectAssertion::new(assertion)); self } pub fn field(&mut self, name: impl Into) -> ObjMemberBuilder> { @@ -922,7 +921,7 @@ let (receiver, name, member) = self.build_member(MaybeUnbound::Bound(Thunk::evaluated(value.into()))); let entry = receiver.0.map.entry(name); - entry.insert(member); + entry.insert_entry(member); } /// Tries to insert value, returns an error if it was already defined @@ -933,7 +932,7 @@ self.binding(MaybeUnbound::Bound(value.into())) } pub fn bindable(self, bindable: impl Unbound) -> Result<()> { - self.binding(MaybeUnbound::Unbound(Cc::new(tb!(bindable)))) + self.binding(MaybeUnbound::Unbound(CcUnbound::new(bindable))) } pub fn binding(self, binding: MaybeUnbound) -> Result<()> { let (receiver, name, member) = self.build_member(binding); @@ -955,8 +954,8 @@ pub fn value(self, value: impl Into) { self.binding(MaybeUnbound::Bound(Thunk::evaluated(value.into()))); } - pub fn bindable(self, bindable: TraceBox>) { - self.binding(MaybeUnbound::Unbound(Cc::new(bindable))); + pub fn bindable(self, bindable: impl Unbound) { + self.binding(MaybeUnbound::Unbound(CcUnbound::new(bindable))); } pub fn binding(self, binding: MaybeUnbound) { let (receiver, name, member) = self.build_member(binding); --- a/crates/jrsonnet-evaluator/src/stack.rs +++ b/crates/jrsonnet-evaluator/src/stack.rs @@ -7,23 +7,41 @@ current_depth: Cell, } -#[cfg(feature = "nightly")] -#[allow(clippy::thread_local_initializer_can_be_made_const)] -#[thread_local] -static STACK_LIMIT: StackLimit = StackLimit { - max_stack_size: Cell::new(200), - current_depth: Cell::new(0), -}; -#[cfg(not(feature = "nightly"))] -thread_local! { - static STACK_LIMIT: StackLimit = const { - StackLimit { - max_stack_size: Cell::new(200), - current_depth: Cell::new(0), +#[cfg(nightly)] +struct NightlyLocalKey(pub T); +#[cfg(nightly)] +impl NightlyLocalKey { + #[inline(always)] + fn with(&self, v: impl FnOnce(&T) -> U) -> U { + v(&self.0) + } +} +#[cfg(not(nightly))] +type NightlyLocalKey = std::thread::LocalKey; + +#[cfg(nightly)] +macro_rules! const_tls { + (const $name:ident: $t:ty = $expr:expr;) => { + #[thread_local] + static $name: NightlyLocalKey<$t> = NightlyLocalKey($expr); + }; +} +#[cfg(not(nightly))] +macro_rules! const_tls { + (const $name:ident: $t:ty = $expr:expr;) => { + thread_local! { + static $name: $t = const { $expr }; } }; } +const_tls! { + const STACK_LIMIT: StackLimit = StackLimit { + max_stack_size: Cell::new(200), + current_depth: Cell::new(0), + }; +} + pub struct StackOverflowError; impl From for ErrorKind { fn from(_: StackOverflowError) -> Self { @@ -39,21 +57,14 @@ /// Used to implement stack depth limitation pub struct StackDepthGuard(PhantomData<()>); impl Drop for StackDepthGuard { - #[cfg(feature = "nightly")] fn drop(&mut self) { - STACK_LIMIT - .current_depth - .set(STACK_LIMIT.current_depth.get() - 1); - } - #[cfg(not(feature = "nightly"))] - fn drop(&mut self) { - STACK_LIMIT.with(|limit| limit.current_depth.set(limit.current_depth.get() - 1)); + STACK_LIMIT.with(|limit| limit.current_depth.set(limit.current_depth.get() - 1)) } } // #[cfg(feature = "nightly")] pub fn check_depth() -> Result { - fn internal(limit: &StackLimit) -> Result { + STACK_LIMIT.with(|limit| { let current = limit.current_depth.get(); if current < limit.max_stack_size.get() { limit.current_depth.set(current + 1); @@ -61,47 +72,26 @@ } else { Err(StackOverflowError) } - } - #[cfg(feature = "nightly")] - { - internal(&STACK_LIMIT) - } - #[cfg(not(feature = "nightly"))] - { - STACK_LIMIT.with(internal) - } + }) } pub struct StackDepthLimitOverrideGuard { old_limit: usize, } impl Drop for StackDepthLimitOverrideGuard { - #[cfg(feature = "nightly")] - fn drop(&mut self) { - STACK_LIMIT.max_stack_size.set(self.old_limit); - } - #[cfg(not(feature = "nightly"))] fn drop(&mut self) { STACK_LIMIT.with(|limit| limit.max_stack_size.set(self.old_limit)); } } pub fn limit_stack_depth(depth_limit: usize) -> StackDepthLimitOverrideGuard { - fn internal(limit: &StackLimit, depth_limit: usize) -> StackDepthLimitOverrideGuard { + STACK_LIMIT.with(|limit| { let old_limit = limit.max_stack_size.get(); let current_depth = limit.current_depth.get(); limit.max_stack_size.set(current_depth + depth_limit); StackDepthLimitOverrideGuard { old_limit } - } - #[cfg(feature = "nightly")] - { - internal(&STACK_LIMIT, depth_limit) - } - #[cfg(not(feature = "nightly"))] - { - STACK_LIMIT.with(|limit| internal(limit, depth_limit)) - } + }) } /// Like [`limit_stack_depth`], but set depth is not guarded, and will be kept --- a/crates/jrsonnet-evaluator/src/trace/mod.rs +++ b/crates/jrsonnet-evaluator/src/trace/mod.rs @@ -1,11 +1,14 @@ +#[cfg(feature = "explaining-traces")] +use std::cell::RefCell; use std::{ any::Any, - cell::RefCell, path::{Path, PathBuf}, }; use jrsonnet_gcmodule::Trace; -use jrsonnet_parser::{CodeLocation, Source, Span}; +use jrsonnet_parser::CodeLocation; +#[cfg(feature = "explaining-traces")] +use jrsonnet_parser::Span; use crate::{error::ErrorKind, Error}; @@ -225,71 +228,6 @@ )?; } else { write!(out, " during {desc}")?; - } - } - Ok(()) - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -/// rustc-like trace displaying -#[cfg(feature = "explaining-traces")] -#[derive(Trace)] -pub struct ExplainingFormat { - pub resolver: PathResolver, - pub max_trace: usize, -} -#[cfg(feature = "explaining-traces")] -impl TraceFormat for ExplainingFormat { - fn write_trace( - &self, - out: &mut dyn std::fmt::Write, - error: &Error, - ) -> Result<(), std::fmt::Error> { - write!(out, "{}", error.error())?; - if let ErrorKind::ImportSyntaxError { path, error } = error.error() { - writeln!(out)?; - let offset = error.location.offset; - let location = path - .map_source_locations(&[offset as u32]) - .into_iter() - .next() - .unwrap(); - let mut end_location = location; - end_location.offset += 1; - - self.print_snippet( - out, - path.code(), - path, - &location, - &end_location, - "syntax error", - )?; - } - let trace = &error.trace(); - for item in &trace.0 { - writeln!(out)?; - let desc = &item.desc; - if let Some(source) = &item.location { - let start_end = source.0.map_source_locations(&[source.1, source.2]); - self.print_snippet( - out, - source.0.code(), - &source.0, - &start_end[0], - &start_end[1], - desc, - )?; - } else { - write!(out, "{desc}")?; } } Ok(()) @@ -305,68 +243,6 @@ } #[cfg(feature = "explaining-traces")] -impl ExplainingFormat { - fn print_snippet( - &self, - out: &mut dyn std::fmt::Write, - source: &str, - origin: &Source, - start: &CodeLocation, - end: &CodeLocation, - desc: &str, - ) -> Result<(), std::fmt::Error> { - use annotate_snippets::{ - // DisplayList, FormatOptions, - AnnotationType, - Renderer, - Slice, - Snippet, - SourceAnnotation, - }; - - let source_fragment: String = source - .chars() - .skip(start.line_start_offset) - .take(end.line_end_offset - end.line_start_offset) - .collect(); - - let origin = origin.source_path().path().map_or_else( - || origin.source_path().to_string(), - |r| self.resolver.resolve(r), - ); - let snippet = Snippet { - // opt: FormatOptions { - // color: true, - // ..FormatOptions::default() - // }, - title: None, - footer: vec![], - slices: vec![Slice { - source: &source_fragment, - line_start: start.line, - origin: Some(&origin), - fold: false, - annotations: vec![SourceAnnotation { - label: desc, - annotation_type: AnnotationType::Error, - range: ( - start.offset - start.line_start_offset, - (end.offset.saturating_sub(start.line_start_offset)) - .min(source_fragment.len()), - ), - }], - }], - }; - - let renderer = Renderer::styled(); - let dl = renderer.render(snippet); - write!(out, "{dl}")?; - - Ok(()) - } -} - -#[cfg(feature = "explaining-traces")] #[derive(Trace)] pub struct HiDocFormat { pub resolver: PathResolver, @@ -390,7 +266,7 @@ let offset = error.location.offset; let mut builder = SnippetBuilder::new(path.code()); builder - .error(Text::single("syntax error".chars(), Formatting::default())) + .error(Text::fragment("syntax error", Formatting::default())) .range(offset..=offset) .build(); let source = builder.build(); @@ -448,7 +324,7 @@ let mut builder = snippet_builder.borrow_mut(); let builder = builder.as_mut().unwrap(); builder - .note(Text::single(desc.chars(), Formatting::default())) + .note(Text::fragment(desc, Formatting::default())) .range(source.1 as usize..=(source.2 as usize - 1).max(source.1 as usize)) .build(); } else { --- a/crates/jrsonnet-evaluator/src/typed/mod.rs +++ b/crates/jrsonnet-evaluator/src/typed/mod.rs @@ -20,9 +20,9 @@ #[error("every failed from {0}:\n{1}")] UnionFailed(ComplexValType, TypeLocErrorList), #[error( - "number out of bounds: {0} not in {}..{}", - .1.map(|v|v.to_string()).unwrap_or_default(), - .2.map(|v|v.to_string()).unwrap_or_default(), + "number out of bounds: {0} not in {start}..{end}", + start = .1.map(|v|v.to_string()).unwrap_or_default(), + end = .2.map(|v|v.to_string()).unwrap_or_default(), )] BoundsFailed(f64, Option, Option), } --- a/crates/jrsonnet-evaluator/src/val.rs +++ b/crates/jrsonnet-evaluator/src/val.rs @@ -8,10 +8,11 @@ rc::Rc, }; -use jrsonnet_gcmodule::{Cc, Trace}; +use jrsonnet_gcmodule::{Acyclic, Cc, Trace, TraceBox}; use jrsonnet_interner::IStr; pub use jrsonnet_macros::Thunk; use jrsonnet_types::ValType; +use rustc_hash::FxHashMap; use thiserror::Error; pub use crate::arr::{ArrValue, ArrayLike}; @@ -19,9 +20,8 @@ bail, error::{Error, ErrorKind::*}, function::FuncVal, - gc::{GcHashMap, TraceBox}, + gc::WithCapacityExt as _, manifest::{ManifestFormat, ToStringFormat}, - tb, typed::BoundedUsize, ObjValue, Result, Unbound, WeakObjValue, }; @@ -70,7 +70,9 @@ Self(Cc::new(RefCell::new(ThunkInner::Computed(val)))) } pub fn new(f: impl ThunkValue + 'static) -> Self { - Self(Cc::new(RefCell::new(ThunkInner::Waiting(tb!(f))))) + Self(Cc::new(RefCell::new(ThunkInner::Waiting(TraceBox( + Box::new(f), + ))))) } pub fn errored(e: Error) -> Self { Self(Cc::new(RefCell::new(ThunkInner::Errored(e)))) @@ -174,13 +176,13 @@ I: Unbound, T: Trace, { - cache: Cc>>, + cache: Cc>>, value: I, } impl, T: Trace> CachedUnbound { pub fn new(value: I) -> Self { Self { - cache: Cc::new(RefCell::new(GcHashMap::new())), + cache: Cc::new(RefCell::new(FxHashMap::new())), value, } } @@ -302,7 +304,7 @@ } } -#[derive(Debug, Clone, Trace)] +#[derive(Debug, Clone, Acyclic)] pub enum StrValue { Flat(IStr), Tree(Rc<(StrValue, StrValue, usize)>), --- a/crates/jrsonnet-interner/src/lib.rs +++ b/crates/jrsonnet-interner/src/lib.rs @@ -9,14 +9,14 @@ borrow::Cow, cell::RefCell, fmt::{self, Display}, - hash::{BuildHasherDefault, Hash, Hasher}, + hash::{Hash, Hasher}, ops::Deref, str, }; use hashbrown::{hash_map::RawEntryMut, HashMap}; -use jrsonnet_gcmodule::Trace; -use rustc_hash::FxHasher; +use jrsonnet_gcmodule::{Acyclic, Trace}; +use rustc_hash::FxBuildHasher; mod inner; use inner::Inner; @@ -31,6 +31,7 @@ false } } +unsafe impl Acyclic for IStr {} impl IStr { #[must_use] @@ -219,10 +220,10 @@ } } -type PoolMap = HashMap>; +type PoolMap = HashMap; thread_local! { - static POOL: RefCell = RefCell::new(HashMap::with_capacity_and_hasher(200, BuildHasherDefault::default())); + static POOL: RefCell = RefCell::new(HashMap::with_capacity_and_hasher(200, FxBuildHasher::default())); } /// Jrsonnet golang bindings require that it is possible to move jsonnet --- a/crates/jrsonnet-macros/src/lib.rs +++ b/crates/jrsonnet-macros/src/lib.rs @@ -103,13 +103,6 @@ syn::custom_keyword!(ok); } -struct EmptyAttr; -impl Parse for EmptyAttr { - fn parse(_input: ParseStream) -> Result { - Ok(Self) - } -} - struct BuiltinAttrs { fields: Vec, } --- a/crates/jrsonnet-parser/src/expr.rs +++ b/crates/jrsonnet-parser/src/expr.rs @@ -4,12 +4,12 @@ rc::Rc, }; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_interner::IStr; use crate::source::Source; -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub enum FieldName { /// {fixed: 2} Fixed(IStr), @@ -17,7 +17,7 @@ Dyn(LocExpr), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)] #[repr(u8)] pub enum Visibility { /// : @@ -34,10 +34,10 @@ } } -#[derive(Clone, Debug, PartialEq, Trace)] +#[derive(Clone, Debug, PartialEq, Acyclic)] pub struct AssertStmt(pub LocExpr, pub Option); -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct FieldMember { pub name: FieldName, pub plus: bool, @@ -46,14 +46,14 @@ pub value: LocExpr, } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub enum Member { Field(FieldMember), BindStmt(BindSpec), AssertStmt(AssertStmt), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)] pub enum UnaryOpType { Plus, Minus, @@ -77,7 +77,7 @@ } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)] pub enum BinaryOpType { Mul, Div, @@ -146,11 +146,11 @@ } /// name, default value -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct Param(pub Destruct, pub Option); /// Defined function parameters -#[derive(Debug, Clone, PartialEq, Trace)] +#[derive(Debug, Clone, PartialEq, Acyclic)] pub struct ParamsDesc(pub Rc>); impl Deref for ParamsDesc { @@ -160,7 +160,7 @@ } } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct ArgsDesc { pub unnamed: Vec, pub named: Vec<(IStr, LocExpr)>, @@ -171,7 +171,7 @@ } } -#[derive(Debug, Clone, PartialEq, Eq, Trace)] +#[derive(Debug, Clone, PartialEq, Eq, Acyclic)] pub enum DestructRest { /// ...rest Keep(IStr), @@ -179,7 +179,7 @@ Drop, } -#[derive(Debug, Clone, PartialEq, Trace)] +#[derive(Debug, Clone, PartialEq, Acyclic)] pub enum Destruct { Full(IStr), #[cfg(feature = "exp-destruct")] @@ -240,7 +240,7 @@ } } -#[derive(Debug, Clone, PartialEq, Trace)] +#[derive(Debug, Clone, PartialEq, Acyclic)] pub enum BindSpec { Field { into: Destruct, @@ -261,19 +261,19 @@ } } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct IfSpecData(pub LocExpr); -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct ForSpecData(pub Destruct, pub LocExpr); -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub enum CompSpec { IfSpec(IfSpecData), ForSpec(ForSpecData), } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct ObjComp { pub pre_locals: Vec, pub field: FieldMember, @@ -281,13 +281,13 @@ pub compspecs: Vec, } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub enum ObjBody { MemberList(Vec), ObjComp(ObjComp), } -#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Acyclic)] pub enum LiteralType { This, Super, @@ -297,7 +297,7 @@ False, } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct SliceDesc { pub start: Option, pub end: Option, @@ -305,7 +305,7 @@ } /// Syntax base -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub enum Expr { Literal(LiteralType), @@ -374,7 +374,7 @@ Slice(LocExpr, SliceDesc), } -#[derive(Debug, PartialEq, Trace)] +#[derive(Debug, PartialEq, Acyclic)] pub struct IndexPart { pub value: LocExpr, #[cfg(feature = "exp-null-coaelse")] @@ -382,8 +382,7 @@ } /// file, begin offset, end offset -#[derive(Clone, PartialEq, Eq, Trace)] -#[trace(skip)] +#[derive(Clone, PartialEq, Eq, Acyclic)] #[repr(C)] pub struct Span(pub Source, pub u32, pub u32); impl Span { @@ -401,7 +400,7 @@ } /// Holds AST expression and its location in source file -#[derive(Clone, PartialEq, Trace)] +#[derive(Clone, PartialEq, Acyclic)] pub struct LocExpr(Rc<(Expr, Span)>); impl LocExpr { pub fn new(expr: Expr, span: Span) -> Self { --- a/crates/jrsonnet-parser/src/source.rs +++ b/crates/jrsonnet-parser/src/source.rs @@ -6,7 +6,7 @@ rc::Rc, }; -use jrsonnet_gcmodule::{Trace, Tracer}; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_interner::{IBytes, IStr}; use crate::location::{location_to_offset, offset_to_location, CodeLocation}; @@ -56,7 +56,7 @@ impl Eq for dyn $T {} }; } -pub trait SourcePathT: Trace + Debug + Display { +pub trait SourcePathT: Acyclic + Debug + Display { /// This method should be checked by resolver before panicking with bad SourcePath input /// if `true` - then resolver may threat this path as default, and default is usally a CWD fn is_default(&self) -> bool; @@ -79,7 +79,7 @@ /// search location is applicable /// /// Resolver may also return custom implementations of this trait, for example it may return http url in case of remotely loaded files -#[derive(Eq, Debug, Clone)] +#[derive(Eq, Debug, Clone, Acyclic)] pub struct SourcePath(Rc); impl SourcePath { pub fn new(inner: impl SourcePathT) -> Self { @@ -106,18 +106,6 @@ &*self.0 == &*other.0 } } -impl Trace for SourcePath { - fn trace(&self, tracer: &mut Tracer) { - (*self.0).trace(tracer) - } - - fn is_type_tracked() -> bool - where - Self: Sized, - { - true - } -} impl Display for SourcePath { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) @@ -129,7 +117,7 @@ } } -#[derive(Trace, Hash, PartialEq, Eq, Debug)] +#[derive(Acyclic, Hash, PartialEq, Eq, Debug)] struct SourceDefault; impl Display for SourceDefault { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -151,7 +139,7 @@ /// /// When `file` is being resolved from `SourceFile(a/b/c)`, it should be resolved to `SourceFile(a/b/file)`, /// however if it is being resolved from `SourceDirectory(a/b/c)`, then it should be resolved to `SourceDirectory(a/b/c/file)` -#[derive(Trace, Hash, PartialEq, Eq, Debug)] +#[derive(Acyclic, Hash, PartialEq, Eq, Debug)] pub struct SourceFile(PathBuf); impl SourceFile { pub fn new(path: PathBuf) -> Self { @@ -179,7 +167,7 @@ /// Represents path to the directory on the disk /// /// See also [`SourceFile`] -#[derive(Trace, Hash, PartialEq, Eq, Debug)] +#[derive(Acyclic, Hash, PartialEq, Eq, Debug)] pub struct SourceDirectory(PathBuf); impl SourceDirectory { pub fn new(path: PathBuf) -> Self { @@ -208,7 +196,7 @@ /// /// It is used for --ext-code=.../--tla-code=.../standard library source code by default, /// and user can construct arbitrary values by hand, without asking import resolver -#[derive(Trace, Hash, PartialEq, Eq, Debug, Clone)] +#[derive(Acyclic, Hash, PartialEq, Eq, Debug, Clone)] pub struct SourceVirtual(pub IStr); impl Display for SourceVirtual { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -231,7 +219,7 @@ /// for better cross-platform support. // PartialEq is limited to ptr equality #[allow(clippy::derived_hash_with_manual_eq)] -#[derive(Trace, Debug, Hash)] +#[derive(Acyclic, Debug, Hash)] pub struct SourceFifo(pub String, pub IBytes); impl PartialEq for SourceFifo { fn eq(&self, other: &Self) -> bool { @@ -258,16 +246,8 @@ /// Either real file, or virtual /// Hash of FileName always have same value as raw Path, to make it possible to use with raw_entry_mut -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Acyclic)] pub struct Source(pub Rc<(SourcePath, IStr)>); - -impl Trace for Source { - fn trace(&self, _tracer: &mut Tracer) {} - - fn is_type_tracked() -> bool { - false - } -} impl Source { pub fn new(path: SourcePath, code: IStr) -> Self { --- a/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs +++ b/crates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rs @@ -127,9 +127,9 @@ IDENT, #[regex("[ \\t\\n\\r]+")] WHITESPACE, - #[regex("//[^\\r\\n]*(\\r\\n|\\n)?")] + #[regex("//[^\\r\\n]*?(\\r\\n|\\n)?")] SINGLE_LINE_SLASH_COMMENT, - #[regex("#[^\\r\\n]*(\\r\\n|\\n)?")] + #[regex("#[^\\r\\n]*?(\\r\\n|\\n)?")] SINGLE_LINE_HASH_COMMENT, #[regex("/\\*([^*]|\\*[^/])*\\*/")] MULTI_LINE_COMMENT, --- a/crates/jrsonnet-stdlib/src/lib.rs +++ b/crates/jrsonnet-stdlib/src/lib.rs @@ -16,7 +16,7 @@ trace::PathResolver, ContextBuilder, IStr, ObjValue, ObjValueBuilder, Thunk, Val, }; -use jrsonnet_gcmodule::Trace; +use jrsonnet_gcmodule::{Acyclic, Cc, Trace}; use jrsonnet_parser::Source; pub use manifest::*; pub use math::*; @@ -50,7 +50,7 @@ mod types; #[allow(clippy::too_many_lines)] -pub fn stdlib_uncached(settings: Rc>) -> ObjValue { +pub fn stdlib_uncached(settings: Cc>) -> ObjValue { let mut builder = ObjValueBuilder::new(); // FIXME: Use PHF @@ -279,10 +279,11 @@ builder.build() } -pub trait TracePrinter { +pub trait TracePrinter: Acyclic { fn print_trace(&self, loc: CallLocation, value: IStr); } +#[derive(Acyclic)] pub struct StdTracePrinter { resolver: PathResolver, } @@ -309,13 +310,14 @@ } } +#[derive(Clone, Trace)] pub struct Settings { /// Used for `std.extVar` pub ext_vars: HashMap, /// Used for `std.native` pub ext_natives: HashMap, /// Used for `std.trace` - pub trace_printer: Box, + pub trace_printer: Rc, /// Used for `std.thisFile` pub path_resolver: PathResolver, } @@ -329,27 +331,27 @@ pub struct ContextInitializer { /// std without applied thisFile overlay stdlib_obj: ObjValue, - settings: Rc>, + settings: Cc>, } impl ContextInitializer { pub fn new(resolver: PathResolver) -> Self { let settings = Settings { ext_vars: HashMap::new(), ext_natives: HashMap::new(), - trace_printer: Box::new(StdTracePrinter::new(resolver.clone())), + trace_printer: Rc::new(StdTracePrinter::new(resolver.clone())), path_resolver: resolver, }; - let settings = Rc::new(RefCell::new(settings)); + let settings = Cc::new(RefCell::new(settings)); let stdlib_obj = stdlib_uncached(settings.clone()); Self { stdlib_obj, settings, } } - pub fn settings(&self) -> Ref { + pub fn settings(&self) -> Ref<'_, Settings> { self.settings.borrow() } - pub fn settings_mut(&self) -> RefMut { + pub fn settings_mut(&self) -> RefMut<'_, Settings> { self.settings.borrow_mut() } pub fn add_ext_var(&self, name: IStr, value: Val) { --- a/crates/jrsonnet-stdlib/src/misc.rs +++ b/crates/jrsonnet-stdlib/src/misc.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, collections::BTreeSet, rc::Rc}; +use std::{cell::RefCell, collections::BTreeSet}; use jrsonnet_evaluator::{ bail, @@ -9,6 +9,7 @@ val::{equals, ArrValue}, Context, Either, IStr, ObjValue, ObjValueBuilder, ResultExt, Thunk, Val, }; +use jrsonnet_gcmodule::Cc; use crate::{extvar_source, Settings}; @@ -47,7 +48,7 @@ } #[builtin(fields( - settings: Rc>, + settings: Cc>, ))] pub fn builtin_ext_var(this: &builtin_ext_var, ctx: Context, x: IStr) -> Result { let ctx = ctx.state().create_default_context(extvar_source(&x, "")); @@ -62,7 +63,7 @@ } #[builtin(fields( - settings: Rc>, + settings: Cc>, ))] pub fn builtin_native(this: &builtin_native, x: IStr) -> Val { this.settings @@ -74,7 +75,7 @@ } #[builtin(fields( - settings: Rc>, + settings: Cc>, ))] pub fn builtin_trace( this: &builtin_trace, --- a/crates/jrsonnet-stdlib/src/regex.rs +++ b/crates/jrsonnet-stdlib/src/regex.rs @@ -1,24 +1,26 @@ -use std::{cell::RefCell, hash::BuildHasherDefault, num::NonZeroUsize, rc::Rc}; +use std::{cell::RefCell, num::NonZeroUsize, rc::Rc}; use ::regex::Regex; use jrsonnet_evaluator::{ error::{ErrorKind::*, Result}, + rustc_hash::FxBuildHasher, val::StrValue, IStr, ObjValueBuilder, Val, }; +use jrsonnet_gcmodule::Acyclic; use jrsonnet_macros::builtin; use lru::LruCache; -use rustc_hash::FxHasher; +#[derive(Acyclic)] pub struct RegexCacheInner { - cache: RefCell, BuildHasherDefault>>, + cache: RefCell, FxBuildHasher>>, } impl Default for RegexCacheInner { fn default() -> Self { Self { cache: RefCell::new(LruCache::with_hasher( NonZeroUsize::new(20).unwrap(), - BuildHasherDefault::default(), + FxBuildHasher::default(), )), } } --- a/flake.lock +++ b/flake.lock @@ -1,17 +1,11 @@ { "nodes": { "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1724377159, - "narHash": "sha256-ixjje1JO8ucKT41hs6n2NCde1Vc0+Zc2p2gUbJpCsMw=", + "lastModified": 1770419512, "owner": "ipetkov", "repo": "crane", - "rev": "3e47b7a86c19142bd3675da49d6acef488b4dac1", + "rev": "2510f2cbc3ccd237f700bb213756a8f35c32d8d7", "type": "github" }, "original": { @@ -27,11 +21,10 @@ ] }, "locked": { - "lastModified": 1722555600, - "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", + "lastModified": 1769996383, "owner": "hercules-ci", "repo": "flake-parts", - "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", "type": "github" }, "original": { @@ -42,15 +35,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1724519568, - "narHash": "sha256-CmfrenY4cEi/mIslKy8XOGdqxUUVgT6/qMzNcAN/7z8=", + "lastModified": 1770468184, "owner": "nixos", "repo": "nixpkgs", - "rev": "eb0e6df0cdd2641ec0651cd9802ff4cff3b3e915", + "rev": "a124a10ea33a73329c42d67f30efcdbfb60a4e04", "type": "github" }, "original": { "owner": "nixos", + "ref": "release-25.11", "repo": "nixpkgs", "type": "github" } @@ -71,11 +64,10 @@ ] }, "locked": { - "lastModified": 1755743804, - "narHash": "sha256-M6qT02voARH5e9eTXQBzpYIE/hAp6jPgBCyxLmw5uBM=", + "lastModified": 1770433312, "owner": "oxalica", "repo": "rust-overlay", - "rev": "80322e975e27d834451d6b66e63f8abae9d74bf2", + "rev": "9922ff9f99a6436756cbe6f5d11f9c3630e58cf0", "type": "github" }, "original": { @@ -85,20 +77,11 @@ } }, "shelly": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1718420551, - "narHash": "sha256-NU8NBXVPj0KuY4Tl/LtZPrbX3PmmmgPuhk/1pzm9cyk=", + "lastModified": 1756323923, "owner": "CertainLach", "repo": "shelly", - "rev": "4f70221f3f9ad9058f590eefb25251b6760aaa47", + "rev": "b5dd29a500db04f54a9f1c2bf81cdd84df8b0cd7", "type": "github" }, "original": { --- a/flake.nix +++ b/flake.nix @@ -1,7 +1,7 @@ { description = "Jrsonnet"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs"; + nixpkgs.url = "github:nixos/nixpkgs/release-25.11"; rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; @@ -10,148 +10,162 @@ url = "github:hercules-ci/flake-parts"; inputs.nixpkgs-lib.follows = "nixpkgs"; }; - crane = { - url = "github:ipetkov/crane"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - shelly = { - url = "github:CertainLach/shelly"; - inputs = { - flake-parts.follows = "flake-parts"; - nixpkgs.follows = "nixpkgs"; - }; - }; + crane.url = "github:ipetkov/crane"; + shelly.url = "github:CertainLach/shelly"; }; - outputs = inputs @ { - nixpkgs, - flake-parts, - rust-overlay, - crane, - shelly, - ... - }: - flake-parts.lib.mkFlake {inherit inputs;} { - imports = [shelly.flakeModule]; - systems = ["x86_64-linux" "aarch64-linux" "armv7l-linux" "armv6l-linux" "mingw-w64"]; - perSystem = { - config, - system, - ... - }: let - pkgs = import nixpkgs { - inherit system; - overlays = [rust-overlay.overlays.default]; - config.allowUnsupportedSystem = true; - }; - rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; - craneLib = (crane.mkLib pkgs).overrideToolchain rust; - in { - legacyPackages = { - jsonnetImpls = { - go-jsonnet = pkgs.callPackage ./nix/go-jsonnet.nix {}; - sjsonnet = pkgs.callPackage ./nix/sjsonnet.nix {}; - jsonnet = pkgs.callPackage ./nix/jsonnet.nix {}; - # I didn't managed to build it, and nixpkgs version is marked as broken - # haskell-jsonnet = pkgs.callPackage ./nix/haskell-jsonnet.nix { }; - rsjsonnet = pkgs.callPackage ./nix/rsjsonnet.nix {}; + outputs = + inputs@{ + nixpkgs, + flake-parts, + rust-overlay, + crane, + shelly, + ... + }: + flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ shelly.flakeModule ]; + systems = inputs.nixpkgs.lib.systems.flakeExposed; + perSystem = + { + config, + system, + ... + }: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ rust-overlay.overlays.default ]; + config.allowUnsupportedSystem = true; + }; + rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + craneLib = (crane.mkLib pkgs).overrideToolchain rust; + in + { + legacyPackages = { + jsonnetImpls = { + go-jsonnet = pkgs.callPackage ./nix/go-jsonnet.nix { }; + sjsonnet = pkgs.callPackage ./nix/sjsonnet.nix { }; + jsonnet = pkgs.callPackage ./nix/jsonnet.nix { }; + # I didn't managed to build it, and nixpkgs version is marked as broken + # haskell-jsonnet = pkgs.callPackage ./nix/haskell-jsonnet.nix { }; + rsjsonnet = pkgs.callPackage ./nix/rsjsonnet.nix { }; + }; }; - }; - packages = rec { - default = jrsonnet; + packages = rec { + default = jrsonnet; - jrsonnet = pkgs.callPackage ./nix/jrsonnet.nix { - inherit craneLib; - }; - jrsonnet-nightly = pkgs.callPackage ./nix/jrsonnet.nix { - inherit craneLib; - withNightlyFeatures = true; - }; - jrsonnet-experimental = pkgs.callPackage ./nix/jrsonnet.nix { - inherit craneLib; - withExperimentalFeatures = true; - }; + jrsonnet = pkgs.callPackage ./nix/jrsonnet.nix { + inherit craneLib; + }; + jrsonnet-nightly = pkgs.callPackage ./nix/jrsonnet.nix { + inherit craneLib; + withNightlyFeatures = true; + }; + jrsonnet-experimental = pkgs.callPackage ./nix/jrsonnet.nix { + inherit craneLib; + withExperimentalFeatures = true; + }; - jrsonnet-release = pkgs.callPackage ./nix/jrsonnet-release.nix { - rustPlatform = pkgs.makeRustPlatform { - rustc = rust; - cargo = rust; + jrsonnet-release = pkgs.callPackage ./nix/jrsonnet-release.nix { + rustPlatform = pkgs.makeRustPlatform { + rustc = rust; + cargo = rust; + }; }; - }; - benchmarks = pkgs.callPackage ./nix/benchmarks.nix { - inherit (config.legacyPackages.jsonnetImpls) go-jsonnet sjsonnet jsonnet rsjsonnet; - jrsonnetVariants = [ - { - drv = jrsonnet.override {forBenchmarks = true;}; - name = ""; - } - ]; + benchmarks = pkgs.callPackage ./nix/benchmarks.nix { + inherit (config.legacyPackages.jsonnetImpls) + go-jsonnet + sjsonnet + jsonnet + rsjsonnet + ; + jrsonnetVariants = [ + { + drv = jrsonnet.override { forBenchmarks = true; }; + name = ""; + } + ]; + }; + benchmarks-quick = pkgs.callPackage ./nix/benchmarks.nix { + inherit (config.legacyPackages.jsonnetImpls) + go-jsonnet + sjsonnet + jsonnet + rsjsonnet + ; + quick = true; + jrsonnetVariants = [ + { + drv = jrsonnet.override { forBenchmarks = true; }; + name = ""; + } + ]; + }; + benchmarks-against-release = pkgs.callPackage ./nix/benchmarks.nix { + inherit (config.legacyPackages.jsonnetImpls) + go-jsonnet + sjsonnet + jsonnet + rsjsonnet + ; + jrsonnetVariants = [ + { + drv = jrsonnet.override { forBenchmarks = true; }; + name = "current"; + } + { + drv = jrsonnet-nightly.override { forBenchmarks = true; }; + name = "current-nightly"; + } + { + drv = jrsonnet-release.override { forBenchmarks = true; }; + name = "release"; + } + ]; + }; + benchmarks-quick-against-release = pkgs.callPackage ./nix/benchmarks.nix { + inherit (config.legacyPackages.jsonnetImpls) + go-jsonnet + sjsonnet + jsonnet + rsjsonnet + ; + quick = true; + jrsonnetVariants = [ + { + drv = jrsonnet.override { forBenchmarks = true; }; + name = "current"; + } + { + drv = jrsonnet-nightly.override { forBenchmarks = true; }; + name = "current-nightly"; + } + { + drv = jrsonnet-release.override { forBenchmarks = true; }; + name = "release"; + } + ]; + }; }; - benchmarks-quick = pkgs.callPackage ./nix/benchmarks.nix { - inherit (config.legacyPackages.jsonnetImpls) go-jsonnet sjsonnet jsonnet rsjsonnet; - quick = true; - jrsonnetVariants = [ - { - drv = jrsonnet.override {forBenchmarks = true;}; - name = ""; - } - ]; - }; - benchmarks-against-release = pkgs.callPackage ./nix/benchmarks.nix { - inherit (config.legacyPackages.jsonnetImpls) go-jsonnet sjsonnet jsonnet rsjsonnet; - jrsonnetVariants = [ - { - drv = jrsonnet.override {forBenchmarks = true;}; - name = "current"; - } - { - drv = jrsonnet-nightly.override {forBenchmarks = true;}; - name = "current-nightly"; - } - { - drv = jrsonnet-release.override {forBenchmarks = true;}; - name = "release"; - } - ]; - }; - benchmarks-quick-against-release = pkgs.callPackage ./nix/benchmarks.nix { - inherit (config.legacyPackages.jsonnetImpls) go-jsonnet sjsonnet jsonnet rsjsonnet; - quick = true; - jrsonnetVariants = [ - { - drv = jrsonnet.override {forBenchmarks = true;}; - name = "current"; - } - { - drv = jrsonnet-nightly.override {forBenchmarks = true;}; - name = "current-nightly"; - } - { - drv = jrsonnet-release.override {forBenchmarks = true;}; - name = "release"; - } - ]; + shelly.shells.default = { + factory = craneLib.devShell; + packages = + with pkgs; + [ + cargo-edit + cargo-outdated + cargo-watch + cargo-insta + cargo-hack + lld + hyperfine + graphviz + ] + ++ lib.optionals (!stdenv.isDarwin) [ + valgrind + ]; }; }; - shelly.shells.default = { - factory = craneLib.devShell; - packages = with pkgs; - [ - alejandra - cargo-edit - cargo-asm - cargo-outdated - cargo-watch - cargo-insta - lld - hyperfine - graphviz - ] - ++ lib.optionals (!stdenv.isDarwin) [ - valgrind - kcachegrind - ]; - }; - }; }; } --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/nd6v7jksg1dqhpx4x4vqgy5ry1nkb9lk-jrsonnet-current \ No newline at end of file --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.89.0" +channel = "1.93.0" components = ["rustfmt", "clippy", "rust-analyzer", "rust-src"] --- a/tests/golden/issue172.jsonnet.golden +++ b/tests/golden/issue172.jsonnet.golden @@ -1,4 +1,4 @@ -variable is not defined: b - issue172.jsonnet:1:45-47: variable access +local is not defined: b + issue172.jsonnet:1:45-47: local access issue172.jsonnet:1:4-10: field access elem <0> evaluation \ No newline at end of file --- a/tests/golden/missing_binding.jsonnet.golden +++ b/tests/golden/missing_binding.jsonnet.golden @@ -1,3 +1,3 @@ -variable is not defined: sta -There is variable with similar name present: std - missing_binding.jsonnet:1:1-5: variable access \ No newline at end of file +local is not defined: sta +There is a local with similar name present: std + missing_binding.jsonnet:1:1-5: local access \ No newline at end of file --- a/tests/tests/common.rs +++ b/tests/tests/common.rs @@ -56,25 +56,10 @@ #[builtin] fn param_names(fun: FuncVal) -> Vec { - match fun { - FuncVal::Id => vec!["x".to_string()], - FuncVal::Normal(func) => func - .params - .iter() - .map(|p| p.0.name().unwrap_or_else(|| "".into()).to_string()) - .collect(), - FuncVal::StaticBuiltin(b) => b - .params() - .iter() - .map(|p| p.name().as_str().unwrap_or("").to_string()) - .collect(), - FuncVal::Builtin(b) => b - .params() - .iter() - .map(|p| p.name().as_str().unwrap_or("").to_string()) - .collect(), - FuncVal::Thunk(_) => vec![], - } + fun.params() + .into_iter() + .map(|v| v.name().as_str().unwrap_or("").to_owned()) + .collect() } #[derive(Trace)] --- a/xtask/src/sourcegen/kinds.rs +++ b/xtask/src/sourcegen/kinds.rs @@ -158,7 +158,6 @@ } use std::{collections::HashSet, str::FromStr}; -pub use define_kinds; use indexmap::IndexMap; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; @@ -266,8 +265,8 @@ error("STRING_BLOCK_MISSING_INDENT", lexer = true); lit("IDENT") => r"[_a-zA-Z][_a-zA-Z0-9]*"; lit("WHITESPACE") => r"[ \t\n\r]+"; - lit("SINGLE_LINE_SLASH_COMMENT") => r"//[^\r\n]*(\r\n|\n)?"; - lit("SINGLE_LINE_HASH_COMMENT") => r"#[^\r\n]*(\r\n|\n)?"; + lit("SINGLE_LINE_SLASH_COMMENT") => r"//[^\r\n]*?(\r\n|\n)?"; + lit("SINGLE_LINE_HASH_COMMENT") => r"#[^\r\n]*?(\r\n|\n)?"; lit("MULTI_LINE_COMMENT") => r"/\*([^*]|\*[^/])*\*/"; error("COMMENT_TOO_SHORT") => r"/\*/"; error("COMMENT_UNTERMINATED") => r"/\*([^*/]|\*[^/])+"; --- a/xtask/src/sourcegen/mod.rs +++ b/xtask/src/sourcegen/mod.rs @@ -4,7 +4,7 @@ use ast::{lower, AstSrc}; use itertools::Itertools; use kinds::{KindsSrc, TokenKind}; -use proc_macro2::{Punct, Spacing, TokenStream}; +use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream}; use quote::{format_ident, quote}; use ungrammar::Grammar; use util::{ensure_file_contents, reformat, to_pascal_case, to_upper_snake_case}; @@ -533,8 +533,11 @@ if "{}[]()$".contains(token) { let c = token.chars().next().unwrap(); quote! { #c } - } else if token.contains('$') { + } else if token.contains(|v| v == '$') { quote! { #token } + } else if token.chars().all(|v| ('a'..='z').contains(&v)) { + let i = Ident::new(&token, Span::call_site()); + quote! { #i } } else { let cs = token.chars().map(|c| Punct::new(c, Spacing::Joint)); quote! { #(#cs)* } -- gitstuff