diff --git a/.trinity/seals/TriCompress.json b/.trinity/seals/TriCompress.json index 8d0826a831..e9762d121c 100644 --- a/.trinity/seals/TriCompress.json +++ b/.trinity/seals/TriCompress.json @@ -1,14 +1,14 @@ { - "gen_hash_c": "sha256:7d671245ce2ff337005cc73bf29326c41f1f50b3ad2f7d1ca641489321065e92", + "gen_hash_c": "sha256:63e362dea9b3329ad95829b552d6fa34f08da0f1755786ad32447799828c51d2", "gen_hash_rust": "sha256:f1597088e21ddbd4bf8ab85f5948d008775cc6a324480942893957ba5b94d1d8", "gen_hash_verilog": "sha256:41d698370fa764f4ec57bb1a90e2a231b1713d333c5715857bf67e04c9fc0931", "gen_hash_zig": "sha256:468fdce272f3c4d97e6a20c99776bffca989143215a594ec62cd4e1ce3d599b1", "module": "TriCompress", "ring": 12, - "sealed_at": "2026-10-07T01:51:55Z", + "sealed_at": "2026-10-07T08:53:00Z", "spec_hash": "sha256:30b32aacead38044923f115734f3a0d38f88bd8caa2c6f75efef3238a8909b0d", "spec_path": "specs/tri/io/compress.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-compress-1848402/spec.zig:27:16: error: use of undeclared identifier 'error'" + "blocked": "does not compile: spec.zig:27:16: error: use of undeclared identifier 'error'" } } \ No newline at end of file diff --git a/.trinity/seals/TriConfig.json b/.trinity/seals/TriConfig.json index f19f14b1bf..50c31caab2 100644 --- a/.trinity/seals/TriConfig.json +++ b/.trinity/seals/TriConfig.json @@ -1,14 +1,14 @@ { - "gen_hash_c": "sha256:5db3173c5d5d39513e958b685ad19380d6beef3e2e0c28a7e624a4e20686a6ec", + "gen_hash_c": "sha256:6c22c8cbb1f366080e899ab378770f777aeb15803a69393fd6be09570ea3da49", "gen_hash_rust": "sha256:d8ccf1fc4cb45257a7ee08a9ff9ea0bfc897b1158fe191836dc6c2198dfcb4cd", "gen_hash_verilog": "sha256:56d2eeb60b68e271520851a1d2fa5e0de5f671a115a9bb3430b1a2c056c2de8f", "gen_hash_zig": "sha256:6395e0965a44273cc35f493b17a74af495822a97b56703771dd1444fae163bd3", "module": "TriConfig", "ring": 12, - "sealed_at": "2026-10-07T01:51:57Z", + "sealed_at": "2026-10-07T08:53:02Z", "spec_hash": "sha256:5b0ee6c43560598a035ff97271295ba459930140467cae84b14ce25d95d494c9", "spec_path": "specs/tri/utils/config.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-config-1848701/spec.zig:47:53: error: use of undeclared identifier 'eq_pos'" + "blocked": "does not compile: spec.zig:47:53: error: use of undeclared identifier 'eq_pos'" } } \ No newline at end of file diff --git a/.trinity/seals/TriFilesystem.json b/.trinity/seals/TriFilesystem.json index 57ec6400d2..bf299ada79 100644 --- a/.trinity/seals/TriFilesystem.json +++ b/.trinity/seals/TriFilesystem.json @@ -1,14 +1,14 @@ { - "gen_hash_c": "sha256:59aa52176495562718dc30d11b75be5ca4b3e6ee4db977769eee550f9371bddd", + "gen_hash_c": "sha256:829da3261d8dd79850e18ba980613a393e1f50c4be979465fbaabf6b30d10768", "gen_hash_rust": "sha256:4cf5ec14a2d46f06fff1dda4ec9fdf1a001943175e9fbc0f81f2931f5e5ba445", "gen_hash_verilog": "sha256:eae1b28013ab3d669db500ae8dbd6fba0f160d9cd844e42cc9d5bd219d178e83", "gen_hash_zig": "sha256:b9010dfec0705ab1c9c9e091d00f18462635d82fb7f0d9ba68c7586028f8ffcb", "module": "TriFilesystem", "ring": 12, - "sealed_at": "2026-10-06T13:02:30Z", + "sealed_at": "2026-10-07T08:53:01Z", "spec_hash": "sha256:45ebfe0502cfcc4b14ed4d052e438d5c95a06a3ab8506fc86c3146379117f5b8", "spec_path": "specs/tri/io/filesystem.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-filesystem-3534046/spec.zig:33:24: error: extra capture in for loop" + "blocked": "does not compile: spec.zig:33:24: error: extra capture in for loop" } } \ No newline at end of file diff --git a/.trinity/seals/TriJson.json b/.trinity/seals/TriJson.json index 875752bf19..f8cf68f702 100644 --- a/.trinity/seals/TriJson.json +++ b/.trinity/seals/TriJson.json @@ -1,14 +1,14 @@ { - "gen_hash_c": "sha256:5514cdf9080a874da8414257516ac17fdab3993f5895b2b8735997d367b03cc7", + "gen_hash_c": "sha256:2c4dec6f4753f05b5c7e6a97e17c456bece89f94dca08df991f137b3fea67072", "gen_hash_rust": "sha256:2900f24252080c50d62beeab5167dc29ae0fba13665ef824fd02dc6491aeae2e", "gen_hash_verilog": "sha256:879bd274778e644d048ed9d9dc8735797f49b29e2d27dc6e319402c170e5ca30", "gen_hash_zig": "sha256:69d52f9c450de32060bf8e9501979d99e186a08047dd412c379b58a132949a9c", "module": "TriJson", "ring": 12, - "sealed_at": "2026-10-05T15:27:55Z", + "sealed_at": "2026-10-07T08:53:00Z", "spec_hash": "sha256:5343625e2ad0f2ccdf56a9a3b3237ac6068441024a13e3d3a26fd24ed54e6c8d", "spec_path": "specs/tri/encoding/json.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-json-2905564/spec.zig:53:18: error: no field or member function named 'parseValue' in 'spec.Parser'" + "blocked": "does not compile: spec.zig:53:18: error: no field or member function named 'parseValue' in 'spec.Parser'" } } \ No newline at end of file diff --git a/.trinity/seals/TriText.json b/.trinity/seals/TriText.json index 08cbccf218..28c6f8bc3f 100644 --- a/.trinity/seals/TriText.json +++ b/.trinity/seals/TriText.json @@ -1,14 +1,14 @@ { - "gen_hash_c": "sha256:4e6928a637e4e19f4ad7723b9c8c5da8eb27d7fba8281e87150d4d560c1c64f6", + "gen_hash_c": "sha256:87cbe457c40956dd35e1619f83cc09114ed34d5c08f33dc596e0edd63b1ca01c", "gen_hash_rust": "sha256:0c5f29ce4b3fb57e768c9d7e8ecc0ce3b4b9a04a126d0d26026af12df8974017", "gen_hash_verilog": "sha256:d912bfa57657942cb5c9fa7b17f4397afff0a33f04e4a151e889be259fcd1a0f", "gen_hash_zig": "sha256:1a558d80c6a540c4348b3d74b60e639649b31f415be1c3fb4dbe389738da120f", "module": "TriText", "ring": 12, - "sealed_at": "2026-10-06T13:02:33Z", + "sealed_at": "2026-10-07T08:53:02Z", "spec_hash": "sha256:0d5c0ce70d13e069af3c01a63da0455776822d78890edba1165fbd03e962e5e1", "spec_path": "specs/tri/utils/text.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-text-3534706/spec.zig:69:17: error: type 'type' not a function" + "blocked": "does not compile: spec.zig:69:17: error: type 'type' not a function" } } \ No newline at end of file diff --git a/.trinity/seals/TriUrl.json b/.trinity/seals/TriUrl.json index 6e8dbfc7a5..ffc5b71044 100644 --- a/.trinity/seals/TriUrl.json +++ b/.trinity/seals/TriUrl.json @@ -1,11 +1,14 @@ { - "gen_hash_c": "sha256:9a63ee856a7e59e09d5b9fab811e624e349694f2e49532d27d95bf6fa1256de9", + "gen_hash_c": "sha256:6716f95b5d99a97f330a99687e28ede4dc4f6a3de2f5c814ba903ea5850bbf78", "gen_hash_rust": "sha256:c349dee90234e99fc9d12a8c8238efe18a8303c75ec387679bba9e511a1498c7", "gen_hash_verilog": "sha256:89fc61f8431e0551a3d5a966b56418cf32fe8a502d4f4ee67814ebb97021e172", "gen_hash_zig": "sha256:c061078961c79a4f3478498b8f0a9da967515ac462a12a713d742f1b08f9bf28", "module": "TriUrl", "ring": 12, - "sealed_at": "2026-10-02T11:02:52Z", + "sealed_at": "2026-10-07T08:53:01Z", "spec_hash": "sha256:cf3d4851c8c6e63e0c26bef53253f0d76b3d652759fb808c4498bb952683e6ee", - "spec_path": "specs/tri/net/url.t27" + "spec_path": "specs/tri/net/url.t27", + "tests": { + "blocked": "does not compile: spec.zig:39:16: error: use of undeclared identifier 'r'" + } } \ No newline at end of file diff --git a/.trinity/seals/api_c_api_contract.json b/.trinity/seals/api_c_api_contract.json index 2196b55f6f..1c8bd670c8 100644 --- a/.trinity/seals/api_c_api_contract.json +++ b/.trinity/seals/api_c_api_contract.json @@ -1,12 +1,16 @@ { - "gen_hash_c": "sha256:cc84ec7bc00ac093f54670cc6b2c023361808f36f256e9edbd2fd71a44f17e76", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:9d332fa4de66ac293c34e686019816a98e1545a6ff3e5a0aea9dec929c1c0829", "gen_hash_rust": "sha256:a6fc3c0868bb39a73b3142083569308af546663ed2bd70f6c2dd54cd675b65aa", "gen_hash_verilog": "sha256:2e7a2aecac7c41713272646ae17f21ddf8cc53b91b4b182cb8f65c5ee21cf2d6", "gen_hash_zig": "sha256:b11e1d22a99313bdf97196b22434ce99a6d34fcf5407127d29a42c231c452842", "module": "c_api_contract", "ring": 12, - "sealed_at": "2026-10-02T11:05:30Z", + "sealed_at": "2026-10-07T08:52:58Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:4ee0aa5df22647ae576218580afe8c567b90a43f23cb4623d24ba28c6b3ba657", - "spec_path": "specs/api/c_api_contract.t27" + "spec_path": "specs/api/c_api_contract.t27", + "tests": { + "blocked": "does not compile: spec.zig:19:17: error: use of undeclared identifier 'trinity_vsa_version'" + } } \ No newline at end of file diff --git a/.trinity/seals/c_api_contract.json b/.trinity/seals/c_api_contract.json index da4b0b89e6..bbf026b74b 100644 --- a/.trinity/seals/c_api_contract.json +++ b/.trinity/seals/c_api_contract.json @@ -1,11 +1,14 @@ { - "gen_hash_c": "sha256:cc84ec7bc00ac093f54670cc6b2c023361808f36f256e9edbd2fd71a44f17e76", + "gen_hash_c": "sha256:9d332fa4de66ac293c34e686019816a98e1545a6ff3e5a0aea9dec929c1c0829", "gen_hash_rust": "sha256:a6fc3c0868bb39a73b3142083569308af546663ed2bd70f6c2dd54cd675b65aa", "gen_hash_verilog": "sha256:2e7a2aecac7c41713272646ae17f21ddf8cc53b91b4b182cb8f65c5ee21cf2d6", "gen_hash_zig": "sha256:b11e1d22a99313bdf97196b22434ce99a6d34fcf5407127d29a42c231c452842", "module": "c_api_contract", "ring": 12, - "sealed_at": "2026-10-02T11:05:30Z", + "sealed_at": "2026-10-07T08:52:58Z", "spec_hash": "sha256:4ee0aa5df22647ae576218580afe8c567b90a43f23cb4623d24ba28c6b3ba657", - "spec_path": "specs/api/c_api_contract.t27" + "spec_path": "specs/api/c_api_contract.t27", + "tests": { + "blocked": "does not compile: spec.zig:19:17: error: use of undeclared identifier 'trinity_vsa_version'" + } } \ No newline at end of file diff --git a/.trinity/seals/encoding_TriJson.json b/.trinity/seals/encoding_TriJson.json index a118585f94..a540e56b17 100644 --- a/.trinity/seals/encoding_TriJson.json +++ b/.trinity/seals/encoding_TriJson.json @@ -1,15 +1,16 @@ { - "gen_hash_c": "sha256:5514cdf9080a874da8414257516ac17fdab3993f5895b2b8735997d367b03cc7", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:2c4dec6f4753f05b5c7e6a97e17c456bece89f94dca08df991f137b3fea67072", "gen_hash_rust": "sha256:2900f24252080c50d62beeab5167dc29ae0fba13665ef824fd02dc6491aeae2e", "gen_hash_verilog": "sha256:879bd274778e644d048ed9d9dc8735797f49b29e2d27dc6e319402c170e5ca30", "gen_hash_zig": "sha256:69d52f9c450de32060bf8e9501979d99e186a08047dd412c379b58a132949a9c", "module": "TriJson", "ring": 12, - "sealed_at": "2026-10-05T15:27:55Z", + "sealed_at": "2026-10-07T08:53:00Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:5343625e2ad0f2ccdf56a9a3b3237ac6068441024a13e3d3a26fd24ed54e6c8d", "spec_path": "specs/tri/encoding/json.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-json-2905564/spec.zig:53:18: error: no field or member function named 'parseValue' in 'spec.Parser'" + "blocked": "does not compile: spec.zig:53:18: error: no field or member function named 'parseValue' in 'spec.Parser'" } } \ No newline at end of file diff --git a/.trinity/seals/io_TriCompress.json b/.trinity/seals/io_TriCompress.json index 63c107c724..cab52f1285 100644 --- a/.trinity/seals/io_TriCompress.json +++ b/.trinity/seals/io_TriCompress.json @@ -1,16 +1,16 @@ { - "built_by": "t27c-bootstrap@0.4.0+403b27f29", - "gen_hash_c": "sha256:7d671245ce2ff337005cc73bf29326c41f1f50b3ad2f7d1ca641489321065e92", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:63e362dea9b3329ad95829b552d6fa34f08da0f1755786ad32447799828c51d2", "gen_hash_rust": "sha256:f1597088e21ddbd4bf8ab85f5948d008775cc6a324480942893957ba5b94d1d8", "gen_hash_verilog": "sha256:41d698370fa764f4ec57bb1a90e2a231b1713d333c5715857bf67e04c9fc0931", "gen_hash_zig": "sha256:468fdce272f3c4d97e6a20c99776bffca989143215a594ec62cd4e1ce3d599b1", "module": "TriCompress", "ring": 12, - "sealed_at": "2026-10-07T01:51:55Z", + "sealed_at": "2026-10-07T08:53:00Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:30b32aacead38044923f115734f3a0d38f88bd8caa2c6f75efef3238a8909b0d", "spec_path": "specs/tri/io/compress.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-compress-1848402/spec.zig:27:16: error: use of undeclared identifier 'error'" + "blocked": "does not compile: spec.zig:27:16: error: use of undeclared identifier 'error'" } } \ No newline at end of file diff --git a/.trinity/seals/io_TriFilesystem.json b/.trinity/seals/io_TriFilesystem.json index 782fc93fca..3a8b7662c7 100644 --- a/.trinity/seals/io_TriFilesystem.json +++ b/.trinity/seals/io_TriFilesystem.json @@ -1,15 +1,16 @@ { - "gen_hash_c": "sha256:59aa52176495562718dc30d11b75be5ca4b3e6ee4db977769eee550f9371bddd", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:829da3261d8dd79850e18ba980613a393e1f50c4be979465fbaabf6b30d10768", "gen_hash_rust": "sha256:4cf5ec14a2d46f06fff1dda4ec9fdf1a001943175e9fbc0f81f2931f5e5ba445", "gen_hash_verilog": "sha256:eae1b28013ab3d669db500ae8dbd6fba0f160d9cd844e42cc9d5bd219d178e83", "gen_hash_zig": "sha256:b9010dfec0705ab1c9c9e091d00f18462635d82fb7f0d9ba68c7586028f8ffcb", "module": "TriFilesystem", "ring": 12, - "sealed_at": "2026-10-06T13:02:30Z", + "sealed_at": "2026-10-07T08:53:01Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:45ebfe0502cfcc4b14ed4d052e438d5c95a06a3ab8506fc86c3146379117f5b8", "spec_path": "specs/tri/io/filesystem.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-filesystem-3534046/spec.zig:33:24: error: extra capture in for loop" + "blocked": "does not compile: spec.zig:33:24: error: extra capture in for loop" } } \ No newline at end of file diff --git a/.trinity/seals/legacy_main_zig_handwritten.json b/.trinity/seals/legacy_main_zig_handwritten.json index cc18b2173a..845558d818 100644 --- a/.trinity/seals/legacy_main_zig_handwritten.json +++ b/.trinity/seals/legacy_main_zig_handwritten.json @@ -1,15 +1,16 @@ { - "gen_hash_c": "sha256:88c4ba2b8d2fc505a49a525079402be1968d1be420c36fc8241d2e8e9239b3b8", + "built_by": "t27c-bootstrap@0.4.0+5ffb20790", + "gen_hash_c": "sha256:2eabfadaa47c21dafad6a599006b53127a615f9a58afdda86fdf777bae0ed99c", "gen_hash_rust": "sha256:91f6e162b63f4688f5e4a515a2c23024ee689394539f04fecde9644b006fa419", "gen_hash_verilog": "sha256:a18ecdc04e1092bd1e8b2ef8e2850a467c90bf3f3fa98709ccb46f69342d0f15", "gen_hash_zig": "sha256:8c72dd1892289701fcd6a126eec1f6c7cfc8c365f706b1eb887a428afd6baf2e", "module": "main_zig_handwritten", "ring": 12, - "sealed_at": "2026-10-06T13:05:53Z", + "sealed_at": "2026-10-07T09:51:44Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:3b65d34b5a660d11c8a0a7e6ca20e1fdccfc64420ae95359c0eeabf13a39f618", "spec_path": "contrib/backend/zig/legacy/main_zig_handwritten.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-main_zig_handwritten-3538823/spec.zig:5:7: error: duplicate struct member name 'std'" + "blocked": "does not compile: spec.zig:5:7: error: duplicate struct member name 'std'" } } \ No newline at end of file diff --git a/.trinity/seals/net_TriUrl.json b/.trinity/seals/net_TriUrl.json index 12b5dec45c..d32d564c81 100644 --- a/.trinity/seals/net_TriUrl.json +++ b/.trinity/seals/net_TriUrl.json @@ -1,12 +1,16 @@ { - "gen_hash_c": "sha256:9a63ee856a7e59e09d5b9fab811e624e349694f2e49532d27d95bf6fa1256de9", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:6716f95b5d99a97f330a99687e28ede4dc4f6a3de2f5c814ba903ea5850bbf78", "gen_hash_rust": "sha256:c349dee90234e99fc9d12a8c8238efe18a8303c75ec387679bba9e511a1498c7", "gen_hash_verilog": "sha256:89fc61f8431e0551a3d5a966b56418cf32fe8a502d4f4ee67814ebb97021e172", "gen_hash_zig": "sha256:c061078961c79a4f3478498b8f0a9da967515ac462a12a713d742f1b08f9bf28", "module": "TriUrl", "ring": 12, - "sealed_at": "2026-10-02T11:02:52Z", + "sealed_at": "2026-10-07T08:53:01Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:cf3d4851c8c6e63e0c26bef53253f0d76b3d652759fb808c4498bb952683e6ee", - "spec_path": "specs/tri/net/url.t27" + "spec_path": "specs/tri/net/url.t27", + "tests": { + "blocked": "does not compile: spec.zig:39:16: error: use of undeclared identifier 'r'" + } } \ No newline at end of file diff --git a/.trinity/seals/utils_TriConfig.json b/.trinity/seals/utils_TriConfig.json index 3354bf2ecc..f14bd363f1 100644 --- a/.trinity/seals/utils_TriConfig.json +++ b/.trinity/seals/utils_TriConfig.json @@ -1,16 +1,16 @@ { - "built_by": "t27c-bootstrap@0.4.0+403b27f29", - "gen_hash_c": "sha256:5db3173c5d5d39513e958b685ad19380d6beef3e2e0c28a7e624a4e20686a6ec", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:6c22c8cbb1f366080e899ab378770f777aeb15803a69393fd6be09570ea3da49", "gen_hash_rust": "sha256:d8ccf1fc4cb45257a7ee08a9ff9ea0bfc897b1158fe191836dc6c2198dfcb4cd", "gen_hash_verilog": "sha256:56d2eeb60b68e271520851a1d2fa5e0de5f671a115a9bb3430b1a2c056c2de8f", "gen_hash_zig": "sha256:6395e0965a44273cc35f493b17a74af495822a97b56703771dd1444fae163bd3", "module": "TriConfig", "ring": 12, - "sealed_at": "2026-10-07T01:51:57Z", + "sealed_at": "2026-10-07T08:53:02Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:5b0ee6c43560598a035ff97271295ba459930140467cae84b14ce25d95d494c9", "spec_path": "specs/tri/utils/config.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-config-1848701/spec.zig:47:53: error: use of undeclared identifier 'eq_pos'" + "blocked": "does not compile: spec.zig:47:53: error: use of undeclared identifier 'eq_pos'" } } \ No newline at end of file diff --git a/.trinity/seals/utils_TriText.json b/.trinity/seals/utils_TriText.json index 9875b9afd8..745958dc18 100644 --- a/.trinity/seals/utils_TriText.json +++ b/.trinity/seals/utils_TriText.json @@ -1,15 +1,16 @@ { - "gen_hash_c": "sha256:4e6928a637e4e19f4ad7723b9c8c5da8eb27d7fba8281e87150d4d560c1c64f6", + "built_by": "t27c-bootstrap@0.4.0+c6f1eec81", + "gen_hash_c": "sha256:87cbe457c40956dd35e1619f83cc09114ed34d5c08f33dc596e0edd63b1ca01c", "gen_hash_rust": "sha256:0c5f29ce4b3fb57e768c9d7e8ecc0ce3b4b9a04a126d0d26026af12df8974017", "gen_hash_verilog": "sha256:d912bfa57657942cb5c9fa7b17f4397afff0a33f04e4a151e889be259fcd1a0f", "gen_hash_zig": "sha256:1a558d80c6a540c4348b3d74b60e639649b31f415be1c3fb4dbe389738da120f", "module": "TriText", "ring": 12, - "sealed_at": "2026-10-06T13:02:33Z", + "sealed_at": "2026-10-07T08:53:02Z", "sealed_by": "t27c-bootstrap@0.4.0", "spec_hash": "sha256:0d5c0ce70d13e069af3c01a63da0455776822d78890edba1165fbd03e962e5e1", "spec_path": "specs/tri/utils/text.t27", "tests": { - "blocked": "does not compile: /tmp/t27c-test-report-text-3534706/spec.zig:69:17: error: type 'type' not a function" + "blocked": "does not compile: spec.zig:69:17: error: type 'type' not a function" } } \ No newline at end of file diff --git a/bootstrap/src/compiler.rs b/bootstrap/src/compiler.rs index 4900d30892..b3a266bbd9 100644 --- a/bootstrap/src/compiler.rs +++ b/bootstrap/src/compiler.rs @@ -19106,6 +19106,30 @@ pub struct CCodegen { /// them writes the global, never a fresh local (#6052). module_var_names: std::collections::HashSet, local_tuple_counter: u32, + /// #7352: the `defer` statements of every block open in the item being + /// emitted, outermost first. A `defer` is not written where it stands; it + /// is written at each exit of its block -- the fall-through end, a + /// `return`, a `break`, a `continue` -- innermost scope first and each + /// scope in reverse order, the order Zig runs them in. Before this the + /// statement reached C as `/* unsupported: StmtExpr */;` and never ran. + c_defer_scopes: Vec, + /// C return type of the fn being emitted, `None` for a void fn, a test, a + /// bench or an invariant body. A `return v;` under a pending `defer` + /// evaluates `v` into a temp of this type before the deferred statements + /// run, as Zig does. + c_current_ret_type: Option, + /// Constructs gen-c refuses rather than lowers (`errdefer`, a `defer` + /// outside any block). `compile_c` fails with these instead of writing C + /// that silently drops a statement. + c_refusals: Vec, +} + +/// One block's pending `defer` statements (#7352). `loop_body` marks the body +/// of a loop: a `break` or `continue` runs the scopes down to and including +/// it, a `return` runs every scope of the item. +struct CDeferScope { + stmts: Vec, + loop_body: bool, } /// The integer width suffix of a typed builtin -- `cast_i8`, `abs_i16`. @@ -19141,6 +19165,9 @@ impl CCodegen { const_defs: std::collections::HashMap::new(), module_var_names: std::collections::HashSet::new(), local_tuple_counter: 0, + c_defer_scopes: Vec::new(), + c_current_ret_type: None, + c_refusals: Vec::new(), } } @@ -21058,9 +21085,10 @@ long double: fabsl, default: llabs)(x)", self.write_indent(); self.write_line("/* TODO: implement */"); } else { - for stmt in &node.children { - self.gen_c_stmt(stmt); - } + self.c_defer_scopes.clear(); + self.c_current_ret_type = (ret_type != "void").then(|| ret_type.clone()); + self.gen_c_body(&node.children, false); + self.c_current_ret_type = None; } self.dedent(); @@ -21113,6 +21141,9 @@ long double: fabsl, default: llabs)(x)", // global never changed and a function reading it still saw 0. bound.extend(self.module_var_names.iter().cloned()); let mut tuple_ctr = 0u32; + self.c_defer_scopes.clear(); + self.c_current_ret_type = None; + self.c_defer_open(false); for stmt in &node.children { let fresh = stmt.kind == NodeKind::StmtAssign && stmt.children.len() >= 2 @@ -21175,6 +21206,7 @@ long double: fabsl, default: llabs)(x)", self.gen_c_stmt(stmt); } } + self.c_defer_close(&node.children); if node.children.is_empty() { self.write_indent(); @@ -21213,9 +21245,9 @@ long double: fabsl, default: llabs)(x)", ); self.write_line(&format!("void {}(void) {{", fn_name)); self.indent(); - for stmt in &node.children { - self.gen_c_stmt(stmt); - } + self.c_defer_scopes.clear(); + self.c_current_ret_type = None; + self.gen_c_body(&node.children, false); self.dedent(); self.write_line("}"); return; @@ -21312,9 +21344,9 @@ long double: fabsl, default: llabs)(x)", self.write_indent(); self.write_line(&format!("/* bench: {} */", node.name)); - for stmt in &node.children { - self.gen_c_stmt(stmt); - } + self.c_defer_scopes.clear(); + self.c_current_ret_type = None; + self.gen_c_body(&node.children, false); if node.children.is_empty() { self.write_indent(); @@ -21344,6 +21376,10 @@ long double: fabsl, default: llabs)(x)", fn gen_c_stmt(&mut self, node: &Node) { match node.kind { NodeKind::ExprReturn => { + if self.c_defer_scopes.iter().any(|s| !s.stmts.is_empty()) { + self.gen_c_return_with_defers(node); + return; + } self.write_indent(); self.write("return "); // The STATEMENT return, distinct from the expression one. The @@ -21353,20 +21389,8 @@ long double: fabsl, default: llabs)(x)", // exists to prevent, one level up. let outer_return = self.c_in_return; self.c_in_return = true; - if !node.children.is_empty() { - // A returned array literal needs the compound-literal cast - // to the fn's [T; N] struct; bare braces are not a C - // expression. - if node.children[0].kind == NodeKind::ExprArrayLiteral { - if let Some(name) = self.current_ret_array_type.clone() { - self.write(&format!("({})", name)); - self.gen_c_array_value(&node.children[0]); - } else { - self.gen_c_expr(&node.children[0]); - } - } else { - self.gen_c_expr(&node.children[0]); - } + if let Some(value) = node.children.first() { + self.gen_c_return_operand(value); } self.c_in_return = outer_return; self.write_line(";"); @@ -21771,11 +21795,36 @@ long double: fabsl, default: llabs)(x)", self.gen_c_for_range_stmt(node); } NodeKind::StmtBreak => { + for stmt in self.c_pending_defers(true) { + self.gen_c_stmt(&stmt); + } self.write_line("break;"); } NodeKind::StmtContinue => { + for stmt in self.c_pending_defers(true) { + self.gen_c_stmt(&stmt); + } self.write_line("continue;"); } + NodeKind::StmtExpr if node.extra_op == "scope_exit" => { + // #7352: `defer S;` -- recorded on the innermost open block and + // written at its exits (`c_defer_close`, `c_pending_defers`). + // `errdefer` runs only on an error return, which C has no + // spelling of here, and a `defer` with no open block has no + // exit to run at: both are refused, never dropped. + match (node.name.as_str(), node.children.first()) { + ("defer", Some(inner)) if !self.c_defer_scopes.is_empty() => { + let inner = inner.clone(); + if let Some(scope) = self.c_defer_scopes.last_mut() { + scope.stmts.push(inner); + } + } + _ => self.c_refusals.push(format!( + "gen-c: `{}` at line {} is not lowered to C (#7352)", + node.name, node.line + )), + } + } NodeKind::StmtExpr => { self.write_indent(); if !node.children.is_empty() { @@ -21791,6 +21840,112 @@ long double: fabsl, default: llabs)(x)", } } + /// Emit a block's statements as one `defer` scope (#7352): the scope opens + /// before the first statement, and the deferred statements run where the + /// block falls through its end. A block that ends in `return`, `break` or + /// `continue` has already run them at that exit. + fn gen_c_body(&mut self, stmts: &[Node], loop_body: bool) { + self.c_defer_open(loop_body); + for stmt in stmts { + self.gen_c_stmt(stmt); + } + self.c_defer_close(stmts); + } + + fn c_defer_open(&mut self, loop_body: bool) { + self.c_defer_scopes.push(CDeferScope { + stmts: Vec::new(), + loop_body, + }); + } + + fn c_defer_close(&mut self, stmts: &[Node]) { + let Some(scope) = self.c_defer_scopes.pop() else { + return; + }; + let exits = stmts.last().is_some_and(|s| { + matches!( + s.kind, + NodeKind::ExprReturn | NodeKind::StmtBreak | NodeKind::StmtContinue + ) + }); + if !exits { + for stmt in scope.stmts.iter().rev() { + self.gen_c_stmt(stmt); + } + } + } + + /// The deferred statements an exit runs: innermost scope first, each scope + /// in reverse order of declaration. `to_loop` (a `break` or `continue`) + /// stops at the innermost loop body and runs nothing when there is none; + /// otherwise (a `return`) every scope of the item runs. + fn c_pending_defers(&self, to_loop: bool) -> Vec { + if to_loop && !self.c_defer_scopes.iter().any(|s| s.loop_body) { + return Vec::new(); + } + let mut out = Vec::new(); + for scope in self.c_defer_scopes.iter().rev() { + out.extend(scope.stmts.iter().rev().cloned()); + if to_loop && scope.loop_body { + break; + } + } + out + } + + /// The operand of a `return`. A returned array literal needs the + /// compound-literal cast to the fn's [T; N] struct; bare braces are not a + /// C expression. + fn gen_c_return_operand(&mut self, value: &Node) { + if value.kind == NodeKind::ExprArrayLiteral { + if let Some(name) = self.current_ret_array_type.clone() { + self.write(&format!("({})", name)); + self.gen_c_array_value(value); + return; + } + } + self.gen_c_expr(value); + } + + /// `return` under a pending `defer` (#7352). Zig evaluates the returned + /// value first and runs the deferred statements after, so a `defer` that + /// changes what the value reads does not change the value. The value goes + /// into a temp, the deferred statements run, the temp is returned. + fn gen_c_return_with_defers(&mut self, node: &Node) { + let defers = self.c_pending_defers(false); + let Some(value) = node.children.first() else { + for stmt in &defers { + self.gen_c_stmt(stmt); + } + self.write_indent(); + self.write_line("return;"); + return; + }; + let ty = self + .c_current_ret_type + .clone() + .unwrap_or_else(|| "__auto_type".to_string()); + self.write_indent(); + self.write_line("{"); + self.indent(); + self.write_indent(); + self.write(&format!("{} __t27_ret = ", ty)); + let outer_return = self.c_in_return; + self.c_in_return = true; + self.gen_c_return_operand(value); + self.c_in_return = outer_return; + self.write_line(";"); + for stmt in &defers { + self.gen_c_stmt(stmt); + } + self.write_indent(); + self.write_line("return __t27_ret;"); + self.dedent(); + self.write_indent(); + self.write_line("}"); + } + fn gen_c_if_stmt(&mut self, node: &Node) { self.write_indent(); self.write("if ("); @@ -21801,9 +21956,7 @@ long double: fabsl, default: llabs)(x)", self.indent(); if node.children.len() > 1 { - for stmt in &node.children[1].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[1].children, false); } self.dedent(); @@ -21817,9 +21970,7 @@ long double: fabsl, default: llabs)(x)", self.write_indent(); self.write_line("} else {"); self.indent(); - for stmt in &else_block.children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&else_block.children, false); self.dedent(); self.write_indent(); self.write_line("}"); @@ -21839,9 +21990,7 @@ long double: fabsl, default: llabs)(x)", self.indent(); if node.children.len() > 1 { - for stmt in &node.children[1].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[1].children, false); } self.dedent(); @@ -21855,9 +22004,7 @@ long double: fabsl, default: llabs)(x)", self.write_indent(); self.write_line("} else {"); self.indent(); - for stmt in &else_block.children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&else_block.children, false); self.dedent(); self.write_indent(); self.write_line("}"); @@ -21886,9 +22033,7 @@ long double: fabsl, default: llabs)(x)", self.indent(); let body_idx = node.children.len().saturating_sub(1); if node.children.len() > 1 { - for stmt in &node.children[body_idx].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[body_idx].children, true); if body_idx > 1 { self.gen_c_stmt(unwrap_single(&node.children[1])); } @@ -21935,9 +22080,7 @@ long double: fabsl, default: llabs)(x)", self.gen_c_expr(&node.children[0].children[1]); self.write_line(&format!("; {var}++) {{")); self.indent(); - for stmt in &node.children[body_idx].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[body_idx].children, true); self.dedent(); self.write_indent(); self.write_line("}"); @@ -21954,9 +22097,7 @@ long double: fabsl, default: llabs)(x)", // Emit body let body_idx = node.children.len().saturating_sub(1); if !node.children.is_empty() { - for stmt in &node.children[body_idx].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[body_idx].children, true); } self.dedent(); @@ -21977,9 +22118,7 @@ long double: fabsl, default: llabs)(x)", self.write_line(" {"); self.indent(); if node.children.len() > 2 { - for stmt in &node.children[2].children { - self.gen_c_stmt(stmt); - } + self.gen_c_body(&node.children[2].children, true); } self.dedent(); self.write_indent(); @@ -23419,6 +23558,9 @@ impl Compiler { // const-inlines `let`, corrupting the source-level output. Fixes #1455. let mut codegen = CCodegen::new(); codegen.gen_c(&ast); + if !codegen.c_refusals.is_empty() { + return Err(codegen.c_refusals.join("\n")); + } Ok(codegen.into_string()) } diff --git a/bootstrap/stage0/FROZEN_HASH b/bootstrap/stage0/FROZEN_HASH index 8ad0c34759..8ee04c154c 100644 --- a/bootstrap/stage0/FROZEN_HASH +++ b/bootstrap/stage0/FROZEN_HASH @@ -1 +1 @@ -c3821827b257808e0d66e8754e22e65b2d361ec5041c55f07ef72e52236c260e bootstrap/src/compiler.rs +82a981e076bb85e55d9d877604412f9787f956177503633e1d8a7382ace7d0a8 bootstrap/src/compiler.rs diff --git a/bootstrap/tests/genc_defer.rs b/bootstrap/tests/genc_defer.rs new file mode 100644 index 0000000000..3c0e41d3ea --- /dev/null +++ b/bootstrap/tests/genc_defer.rs @@ -0,0 +1,207 @@ +//! #7352: gen-c wrote `defer S;` as the comment `/* unsupported: StmtExpr */;`, +//! exited 0, and the deferred statement never ran. A test that depended on it +//! trapped at run time; one that did not passed while the cleanup it claimed +//! never happened. +//! +//! gen-c now writes the deferred statement at every exit of its block, the way +//! Zig runs it: at the fall-through end, before a `return` (after the returned +//! value is evaluated), before a `break` or `continue` of the loop whose body +//! declared it, innermost block first and each block in reverse order of +//! declaration. `errdefer` is refused by name and line, never dropped. +//! +//! Every test compiles the generated C with `-DT27_TEST_MAIN` and RUNS it: the +//! defect compiled cleanly, so only running the C shows the call happened. +//! +//! Part of #5980. + +use std::path::PathBuf; +use std::process::{Command, Output}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static N: AtomicUsize = AtomicUsize::new(0); + +struct Scratch(PathBuf); +impl Scratch { + fn new() -> Self { + let d = std::env::temp_dir().join(format!( + "t27c-genc-defer-{}-{}", + std::process::id(), + N.fetch_add(1, Ordering::Relaxed) + )); + let _ = std::fs::remove_dir_all(&d); + std::fs::create_dir_all(&d).expect("create scratch directory"); + Self(d) + } +} +impl Drop for Scratch { + fn drop(&mut self) { + let _ = std::fs::remove_dir_all(&self.0); + } +} + +fn gen_c_raw(s: &Scratch, src: &str) -> Output { + let p = s.0.join("in.t27"); + std::fs::write(&p, src).expect("write spec"); + Command::new(env!("CARGO_BIN_EXE_t27c")) + .arg("gen-c") + .arg(&p) + .output() + .expect("run t27c gen-c") +} + +fn gen_c(s: &Scratch, src: &str) -> String { + let out = gen_c_raw(s, src); + assert!( + out.status.success(), + "gen-c failed:\n{}", + String::from_utf8_lossy(&out.stderr) + ); + String::from_utf8_lossy(&out.stdout).to_string() +} + +fn cc_present() -> bool { + Command::new("cc") + .arg("--version") + .output() + .map(|o| o.status.success()) + .unwrap_or(false) +} + +/// Generate C for `src`, refuse an `unsupported` comment, then compile it with +/// the built-in test runner and run it. Returns the C. The run is skipped +/// where there is no cc; the text checks are not. +fn gen_and_run(src: &str) -> String { + let s = Scratch::new(); + let c = gen_c(&s, src); + assert!( + !c.contains("unsupported"), + "gen-c wrote a statement as `unsupported`:\n{}", + c + ); + if !cc_present() { + eprintln!("cc not found; skipping the run"); + return c; + } + let cp = s.0.join("out.c"); + std::fs::write(&cp, &c).expect("write C"); + let bin = s.0.join("out"); + let built = Command::new("cc") + .args(["-std=gnu11", "-DT27_TEST_MAIN"]) + .arg(&cp) + .arg("-o") + .arg(&bin) + .output() + .expect("run cc"); + assert!( + built.status.success(), + "cc refused the generated C:\n{}\n--- C ---\n{}", + String::from_utf8_lossy(&built.stderr), + c + ); + let ran = Command::new(&bin).output().expect("run the generated C"); + assert!( + ran.status.success(), + "the generated C failed its own tests ({}):\n{}{}\n--- C ---\n{}", + ran.status, + String::from_utf8_lossy(&ran.stdout), + String::from_utf8_lossy(&ran.stderr), + c + ); + c +} + +/// The issue's reproduction, verbatim. +const ISSUE_REPRO: &str = "module m;\nvar n: i64 = 0;\nfn inc() -> void { n = n + 1; }\n\ +fn f() -> void {\n defer inc();\n}\ntest t { f(); assert(n == 1); }\n"; + +#[test] +fn the_issue_repro_runs_the_deferred_call() { + gen_and_run(ISSUE_REPRO); +} + +/// `a` then `b` appended as digits: 21 means `b` ran first. +const TRACE: &str = "module m;\nvar trace: i64 = 0;\n\ +fn a() -> void { trace = trace * 10 + 1; }\n\ +fn b() -> void { trace = trace * 10 + 2; }\n"; + +#[test] +fn two_defers_run_in_reverse_order() { + gen_and_run(&format!( + "{TRACE}fn f() -> void {{\n defer a();\n defer b();\n}}\n\ + test t {{ f(); assert(trace == 21); }}\n" + )); +} + +#[test] +fn an_inner_block_runs_before_the_outer_one_on_return() { + gen_and_run(&format!( + "{TRACE}fn f(x: i64) -> void {{\n defer a();\n if (x > 0) {{\n defer b();\n return;\n }}\n}}\n\ + test t {{ f(1); assert(trace == 21); f(0); assert(trace == 211); }}\n" + )); +} + +const COUNTER: &str = "module m;\nvar n: i64 = 0;\nfn inc() -> void { n = n + 1; }\n"; + +#[test] +fn an_early_return_runs_the_deferred_call() { + gen_and_run(&format!( + "{COUNTER}fn g(x: i64) -> i64 {{\n defer inc();\n if (x > 0) {{\n return x;\n }}\n return 0;\n}}\n\ + test t {{ assert(g(5) == 5); assert(n == 1); assert(g(0) == 0); assert(n == 2); }}\n" + )); +} + +#[test] +fn the_returned_value_is_read_before_the_deferred_call_runs() { + gen_and_run( + "module m;\nvar n: i64 = 0;\nfn reset() -> void { n = 0; }\n\ + fn h() -> i64 {\n n = 7;\n defer reset();\n return n;\n}\n\ + test t { assert(h() == 7); assert(n == 0); }\n", + ); +} + +#[test] +fn break_runs_the_loop_body_defer() { + gen_and_run(&format!( + "{COUNTER}fn f() -> i64 {{\n var i: i64 = 0;\n while (i < 10) {{\n defer inc();\n i = i + 1;\n if (i == 3) {{\n break;\n }}\n }}\n return i;\n}}\n\ + test t {{ assert(f() == 3); assert(n == 3); }}\n" + )); +} + +#[test] +fn continue_runs_the_loop_body_defer() { + gen_and_run(&format!( + "{COUNTER}fn f() -> i64 {{\n var i: i64 = 0;\n var skipped: i64 = 0;\n while (i < 4) {{\n defer inc();\n i = i + 1;\n if (i < 10) {{\n continue;\n }}\n skipped = 1;\n }}\n return skipped;\n}}\n\ + test t {{ assert(f() == 0); assert(n == 4); }}\n" + )); +} + +#[test] +fn a_loop_defer_does_not_run_on_the_fn_return_twice() { + // The loop body's scope is closed when the loop ends, so the `return` + // after it runs only the fn's own defer. + gen_and_run(&format!( + "{TRACE}fn f() -> void {{\n defer a();\n var i: i64 = 0;\n while (i < 2) {{\n defer b();\n i = i + 1;\n }}\n return;\n}}\n\ + test t {{ f(); assert(trace == 221); }}\n" + )); +} + +#[test] +fn errdefer_is_refused_by_name_and_line() { + let s = Scratch::new(); + let out = gen_c_raw( + &s, + "module m;\nvar n: i64 = 0;\nfn inc() -> void { n = n + 1; }\n\ + fn f() -> void {\n errdefer inc();\n}\n", + ); + let stderr = String::from_utf8_lossy(&out.stderr); + assert!( + !out.status.success(), + "gen-c accepted an errdefer it cannot lower:\n{}", + String::from_utf8_lossy(&out.stdout) + ); + assert!( + stderr.contains("`errdefer` at line 5"), + "the refusal must name `errdefer` and its line:\n{}", + stderr + ); +} diff --git a/tools/policy/foreign-exceptions.txt b/tools/policy/foreign-exceptions.txt index 7e339c4471..4a1dc77a97 100644 --- a/tools/policy/foreign-exceptions.txt +++ b/tools/policy/foreign-exceptions.txt @@ -186,6 +186,12 @@ bootstrap/tests/core_selfhost.rs # lowers byte-identically to gen-c; the new shapes themselves are fixtures. bootstrap/tests/core_selfhost.rs +# owner 2026-10-07, standing rule ("add the label yourself and do the foreign part", translated), gen-c +# defects lane of epic #5980 (self-host P1), issue #7352: gen-c writes `defer` at every exit of its block +# instead of an `unsupported` comment; the test compiles and RUNS the C. compiler.rs and FROZEN_HASH are +# listed above. +bootstrap/tests/genc_defer.rs + # one-time 2026-10-06, merge route for #6804 (Refs #6803): master-side mods of label-gated #6826/#6847 # ride the combined diff and trip the local own-language hook on the merge commit. Standing owner # authorization 2026-10-06 ("add the label yourself and do the foreign part", translated). Same four