guppylang-internals 0.26.0__tar.gz → 0.27.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/CHANGELOG.md +30 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/PKG-INFO +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/pyproject.toml +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/__init__.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/cfg/builder.py +3 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/linearity.py +6 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/expr_checker.py +26 -11
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/expr_compiler.py +30 -8
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/modifier_compiler.py +5 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/decorator.py +3 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/function.py +20 -7
- guppylang_internals-0.27.0/src/guppylang_internals/definition/metadata.py +87 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/overloaded.py +11 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/pytket_circuits.py +6 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/diagnostic.py +72 -15
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/engine.py +1 -10
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/nodes.py +32 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/array.py +36 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/either.py +14 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/tket_bool.py +1 -6
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/tket_exts.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/object.py +4 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/wasm_util.py +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/.gitignore +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/LICENCE +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/README.md +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/ast_util.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/cfg/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/cfg/analysis.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/cfg/bb.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/cfg/cfg.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/cfg_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/core.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/comptime_errors.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/generic.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/type_errors.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/errors/wasm.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/func_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/linearity_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/modifier_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/stmt_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/checker/unitary_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/cfg_compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/core.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/func_compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/hugr_extension.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/qtm_platform_extension.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/compiler/stmt_compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/common.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/const.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/custom.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/declaration.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/extern.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/parameter.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/struct.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/traced.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/ty.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/value.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/definition/wasm.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/dummy_decorator.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/error.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/experimental.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/ipython_inspect.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/py.typed +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/span.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/arithmetic.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/frozenarray.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/futures.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/list.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/mem.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/option.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/platform.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/prelude.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/qsystem.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/quantum.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler/wasm.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/debug.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/std/_internal/util.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/builtins_mock.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/frozenlist.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/function.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/state.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/unpacking.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tracing/util.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/arg.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/builtin.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/common.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/const.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/errors.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/param.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/parsing.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/printing.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/qubit.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/subst.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/ty.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/tys/var.py +0 -0
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
First release of `guppylang_internals` package containing refactored out internal components
|
|
4
4
|
from `guppylang`.
|
|
5
5
|
|
|
6
|
+
## [0.27.0](https://github.com/Quantinuum/guppylang/compare/guppylang-internals-v0.26.0...guppylang-internals-v0.27.0) (2026-01-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* The first argument to `add_unitarity_metadata` is now named `node`
|
|
12
|
+
instead of `func`, since its type was raised to allow for more HUGR
|
|
13
|
+
nodes to be fed. Migration is trivial.
|
|
14
|
+
* `DiagnosticsRenderer.PREFIX_CONTEXT_LINES` constant has been removed.
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* Add qubit hints on Guppy functions, allowing elision when building emulators ([#1378](https://github.com/Quantinuum/guppylang/issues/1378)) ([b7f10c6](https://github.com/Quantinuum/guppylang/commit/b7f10c6798aa20841fae844084d8a1606661fd7b)), closes [#1297](https://github.com/Quantinuum/guppylang/issues/1297)
|
|
19
|
+
* Add unsafe array take and put operations ([#1165](https://github.com/Quantinuum/guppylang/issues/1165)) ([7f342e7](https://github.com/Quantinuum/guppylang/commit/7f342e788e2f179382bab46dcc7e69a24dd64de3))
|
|
20
|
+
* **internals:** update to hugr-py 0.15 ([#1418](https://github.com/Quantinuum/guppylang/issues/1418)) ([cf970ba](https://github.com/Quantinuum/guppylang/commit/cf970ba7403a126fbd5d2fd53445e65270581df4))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* Add a line break for printing WASM files ([#1386](https://github.com/Quantinuum/guppylang/issues/1386)) ([495aba5](https://github.com/Quantinuum/guppylang/commit/495aba5b9bb2218224193c7b2da2c5586744505a))
|
|
26
|
+
* added deepcopy in `OverloadedFunctionDef.{check_call,synthesize_call}` ([#1426](https://github.com/Quantinuum/guppylang/issues/1426)) ([9be6fef](https://github.com/Quantinuum/guppylang/commit/9be6fefcdfb9fc9eb1025774d2dd2727b3e719b1))
|
|
27
|
+
* **checker:** handle imported ParamDef with aliases in expr_checker ([#1385](https://github.com/Quantinuum/guppylang/issues/1385)) ([f2838a3](https://github.com/Quantinuum/guppylang/commit/f2838a34a315599c5b46eae92b72e9758e428a16))
|
|
28
|
+
* Convert symbolic pytket circuits angle inputs into rotations ([#1425](https://github.com/Quantinuum/guppylang/issues/1425)) ([4724d90](https://github.com/Quantinuum/guppylang/commit/4724d9039d8dffae8fd939f62ae80ec307d8918a))
|
|
29
|
+
* Ensure errors from `[@wasm](https://github.com/wasm)_module` are rendered correctly ([#1398](https://github.com/Quantinuum/guppylang/issues/1398)) ([a6a539f](https://github.com/Quantinuum/guppylang/commit/a6a539fe07cc94f4a788fef506969e4c9027faee)), closes [#1397](https://github.com/Quantinuum/guppylang/issues/1397)
|
|
30
|
+
* Fix another wasm diagnostics rendering issue ([#1399](https://github.com/Quantinuum/guppylang/issues/1399)) ([6604175](https://github.com/Quantinuum/guppylang/commit/660417542f2b36c387e73765f8647c11cd3d1a7b))
|
|
31
|
+
* Fix Hugr generation for tuples in `Result` and `Either` ([#1395](https://github.com/Quantinuum/guppylang/issues/1395)) ([f8b0d47](https://github.com/Quantinuum/guppylang/commit/f8b0d47eb275aae3f5ba804dfeb3640c4a3baef6)), closes [#1388](https://github.com/Quantinuum/guppylang/issues/1388)
|
|
32
|
+
* improve diagnostics rendering ([#1382](https://github.com/Quantinuum/guppylang/issues/1382)) ([e7ce7f6](https://github.com/Quantinuum/guppylang/commit/e7ce7f6d1a4f2b12ff680a6e54dae96637c5fa92))
|
|
33
|
+
* Stop parsing entrypoints twice ([#1410](https://github.com/Quantinuum/guppylang/issues/1410)) ([4a167e5](https://github.com/Quantinuum/guppylang/commit/4a167e5642cedc8f47ad027ed08483caa1558830))
|
|
34
|
+
* Support comptime expressions in generic argument applications ([#1409](https://github.com/Quantinuum/guppylang/issues/1409)) ([c1aad34](https://github.com/Quantinuum/guppylang/commit/c1aad346adb15e3636e5586987422d74e36189a1)), closes [#1087](https://github.com/Quantinuum/guppylang/issues/1087)
|
|
35
|
+
|
|
6
36
|
## [0.26.0](https://github.com/Quantinuum/guppylang/compare/guppylang-internals-v0.25.0...guppylang-internals-v0.26.0) (2025-12-11)
|
|
7
37
|
|
|
8
38
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guppylang-internals
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: Compiler internals for `guppylang` package.
|
|
5
5
|
Author-email: Mark Koch <mark.koch@quantinuum.com>, TKET development team <tket-support@quantinuum.com>
|
|
6
6
|
Maintainer-email: Mark Koch <mark.koch@quantinuum.com>, TKET development team <tket-support@quantinuum.com>
|
|
@@ -219,7 +219,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
219
219
|
Classifier: Programming Language :: Python :: 3.14
|
|
220
220
|
Classifier: Topic :: Software Development :: Compilers
|
|
221
221
|
Requires-Python: <4,>=3.10
|
|
222
|
-
Requires-Dist: hugr~=0.
|
|
222
|
+
Requires-Dist: hugr~=0.15.0
|
|
223
223
|
Requires-Dist: tket-exts~=0.12.0
|
|
224
224
|
Requires-Dist: typing-extensions<5,>=4.9.0
|
|
225
225
|
Requires-Dist: wasmtime~=v38.0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "guppylang-internals"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.27.0"
|
|
4
4
|
requires-python = ">=3.10,<4"
|
|
5
5
|
description = "Compiler internals for `guppylang` package."
|
|
6
6
|
license = { file = "LICENCE" }
|
|
@@ -35,7 +35,7 @@ classifiers = [
|
|
|
35
35
|
dependencies = [
|
|
36
36
|
"typing-extensions >=4.9.0,<5",
|
|
37
37
|
"tket-exts ~= 0.12.0",
|
|
38
|
-
"hugr ~= 0.
|
|
38
|
+
"hugr ~= 0.15.0",
|
|
39
39
|
"wasmtime ~= v38.0.0",
|
|
40
40
|
]
|
|
41
41
|
|
|
@@ -33,7 +33,9 @@ class AlreadyUsedError(Error):
|
|
|
33
33
|
|
|
34
34
|
@dataclass(frozen=True)
|
|
35
35
|
class PrevUse(Note):
|
|
36
|
-
span_label: ClassVar[str] =
|
|
36
|
+
span_label: ClassVar[str] = (
|
|
37
|
+
"{place.describe} already {prev_kind.subjunctive} here"
|
|
38
|
+
)
|
|
37
39
|
prev_kind: UseKind
|
|
38
40
|
|
|
39
41
|
@dataclass(frozen=True)
|
|
@@ -55,7 +57,9 @@ class ComprAlreadyUsedError(Error):
|
|
|
55
57
|
|
|
56
58
|
@dataclass(frozen=True)
|
|
57
59
|
class PrevUse(Note):
|
|
58
|
-
span_label: ClassVar[str] =
|
|
60
|
+
span_label: ClassVar[str] = (
|
|
61
|
+
"{place.describe} already {prev_kind.subjunctive} here"
|
|
62
|
+
)
|
|
59
63
|
prev_kind: UseKind
|
|
60
64
|
|
|
61
65
|
|
|
@@ -85,6 +85,7 @@ from guppylang_internals.checker.errors.type_errors import (
|
|
|
85
85
|
WrongNumberOfArgsError,
|
|
86
86
|
)
|
|
87
87
|
from guppylang_internals.definition.common import Definition
|
|
88
|
+
from guppylang_internals.definition.parameter import ParamDef
|
|
88
89
|
from guppylang_internals.definition.ty import TypeDef
|
|
89
90
|
from guppylang_internals.definition.value import CallableDef, ValueDef
|
|
90
91
|
from guppylang_internals.error import (
|
|
@@ -407,23 +408,27 @@ class ExprSynthesizer(AstVisitor[tuple[ast.expr, Type]]):
|
|
|
407
408
|
raise GuppyError(IllegalConstant(node, type(node.value)))
|
|
408
409
|
return node, ty
|
|
409
410
|
|
|
411
|
+
def _check_generic_param(self, name: str, node: ast.expr) -> tuple[ast.expr, Type]:
|
|
412
|
+
"""Helper method to check a generic parameter (ConstParam or TypeParam)."""
|
|
413
|
+
param = self.ctx.generic_params[name]
|
|
414
|
+
match param:
|
|
415
|
+
case ConstParam() as param:
|
|
416
|
+
ast_node = with_loc(node, GenericParamValue(id=name, param=param))
|
|
417
|
+
return ast_node, param.ty
|
|
418
|
+
case TypeParam() as param:
|
|
419
|
+
raise GuppyError(
|
|
420
|
+
ExpectedError(node, "a value", got=f"type `{param.name}`")
|
|
421
|
+
)
|
|
422
|
+
case _:
|
|
423
|
+
return assert_never(param)
|
|
424
|
+
|
|
410
425
|
def visit_Name(self, node: ast.Name) -> tuple[ast.expr, Type]:
|
|
411
426
|
x = node.id
|
|
412
427
|
if x in self.ctx.locals:
|
|
413
428
|
var = self.ctx.locals[x]
|
|
414
429
|
return with_loc(node, PlaceNode(place=var)), var.ty
|
|
415
430
|
elif x in self.ctx.generic_params:
|
|
416
|
-
|
|
417
|
-
match param:
|
|
418
|
-
case ConstParam() as param:
|
|
419
|
-
ast_node = with_loc(node, GenericParamValue(id=x, param=param))
|
|
420
|
-
return ast_node, param.ty
|
|
421
|
-
case TypeParam() as param:
|
|
422
|
-
raise GuppyError(
|
|
423
|
-
ExpectedError(node, "a value", got=f"type `{param.name}`")
|
|
424
|
-
)
|
|
425
|
-
case _:
|
|
426
|
-
return assert_never(param)
|
|
431
|
+
return self._check_generic_param(x, node)
|
|
427
432
|
elif x in self.ctx.globals:
|
|
428
433
|
match self.ctx.globals[x]:
|
|
429
434
|
case Definition() as defn:
|
|
@@ -454,6 +459,16 @@ class ExprSynthesizer(AstVisitor[tuple[ast.expr, Type]]):
|
|
|
454
459
|
defn, "__new__"
|
|
455
460
|
):
|
|
456
461
|
return with_loc(node, GlobalName(id=name, def_id=constr.id)), constr.ty
|
|
462
|
+
# Handle parameter definitions (e.g., nat_var) that may be imported
|
|
463
|
+
case ParamDef():
|
|
464
|
+
# Check if this parameter is in our generic_params
|
|
465
|
+
# (e.g., used in type signature)
|
|
466
|
+
if name in self.ctx.generic_params:
|
|
467
|
+
return self._check_generic_param(name, node)
|
|
468
|
+
# If not in generic_params, it's being used outside its scope
|
|
469
|
+
raise GuppyError(
|
|
470
|
+
ExpectedError(node, "a value", got=f"{defn.description} `{name}`")
|
|
471
|
+
)
|
|
457
472
|
case defn:
|
|
458
473
|
raise GuppyError(
|
|
459
474
|
ExpectedError(node, "a value", got=f"{defn.description} `{name}`")
|
|
@@ -325,14 +325,7 @@ class ExprCompiler(CompilerBase, AstVisitor[Wire]):
|
|
|
325
325
|
|
|
326
326
|
def _pack_returns(self, returns: Sequence[Wire], return_ty: Type) -> Wire:
|
|
327
327
|
"""Groups function return values into a tuple"""
|
|
328
|
-
|
|
329
|
-
types = type_to_row(return_ty)
|
|
330
|
-
assert len(returns) == len(types)
|
|
331
|
-
return self._pack_tuple(returns, types)
|
|
332
|
-
assert (
|
|
333
|
-
len(returns) == 1
|
|
334
|
-
), f"Expected a single return value. Got {returns}. return type {return_ty}"
|
|
335
|
-
return returns[0]
|
|
328
|
+
return pack_returns(returns, return_ty, self.builder, self.ctx)
|
|
336
329
|
|
|
337
330
|
def _update_inout_ports(
|
|
338
331
|
self,
|
|
@@ -760,6 +753,35 @@ def expr_to_row(expr: ast.expr) -> list[ast.expr]:
|
|
|
760
753
|
return expr.elts if isinstance(expr, ast.Tuple) else [expr]
|
|
761
754
|
|
|
762
755
|
|
|
756
|
+
def pack_returns(
|
|
757
|
+
returns: Sequence[Wire],
|
|
758
|
+
return_ty: Type,
|
|
759
|
+
builder: DfBase[ops.DfParentOp],
|
|
760
|
+
ctx: CompilerContext,
|
|
761
|
+
) -> Wire:
|
|
762
|
+
"""Groups function return values into a tuple"""
|
|
763
|
+
if isinstance(return_ty, TupleType | NoneType) and not return_ty.preserve:
|
|
764
|
+
types = type_to_row(return_ty)
|
|
765
|
+
assert len(returns) == len(types)
|
|
766
|
+
hugr_tys = [t.to_hugr(ctx) for t in types]
|
|
767
|
+
return builder.add_op(ops.MakeTuple(hugr_tys), *returns)
|
|
768
|
+
assert (
|
|
769
|
+
len(returns) == 1
|
|
770
|
+
), f"Expected a single return value. Got {returns}. return type {return_ty}"
|
|
771
|
+
return returns[0]
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def unpack_wire(
|
|
775
|
+
wire: Wire, return_ty: Type, builder: DfBase[ops.DfParentOp], ctx: CompilerContext
|
|
776
|
+
) -> list[Wire]:
|
|
777
|
+
"""The inverse of `pack_returns`"""
|
|
778
|
+
if isinstance(return_ty, TupleType | NoneType) and not return_ty.preserve:
|
|
779
|
+
types = type_to_row(return_ty)
|
|
780
|
+
hugr_tys = [t.to_hugr(ctx) for t in types]
|
|
781
|
+
return list(builder.add_op(ops.UnpackTuple(hugr_tys), wire).outputs())
|
|
782
|
+
return [wire]
|
|
783
|
+
|
|
784
|
+
|
|
763
785
|
def instantiation_needs_unpacking(func_ty: FunctionType, inst: Inst) -> bool:
|
|
764
786
|
"""Checks if instantiating a polymorphic makes it return a row."""
|
|
765
787
|
if isinstance(func_ty.output, BoundTypeVar):
|
|
@@ -8,7 +8,7 @@ from guppylang_internals.checker.modifier_checker import non_copyable_front_othe
|
|
|
8
8
|
from guppylang_internals.compiler.cfg_compiler import compile_cfg
|
|
9
9
|
from guppylang_internals.compiler.core import CompilerContext, DFContainer
|
|
10
10
|
from guppylang_internals.compiler.expr_compiler import ExprCompiler
|
|
11
|
-
from guppylang_internals.definition.
|
|
11
|
+
from guppylang_internals.definition.metadata import add_metadata
|
|
12
12
|
from guppylang_internals.nodes import CheckedModifiedBlock, PlaceNode
|
|
13
13
|
from guppylang_internals.std._internal.compiler.array import (
|
|
14
14
|
array_new,
|
|
@@ -57,7 +57,10 @@ def compile_modified_block(
|
|
|
57
57
|
func_builder = dfg.builder.module_root_builder().define_function(
|
|
58
58
|
str(modified_block), hugr_ty.input, hugr_ty.output
|
|
59
59
|
)
|
|
60
|
-
|
|
60
|
+
add_metadata(
|
|
61
|
+
func_builder,
|
|
62
|
+
additional_metadata={"unitary": modified_block.ty.unitary_flags.value},
|
|
63
|
+
)
|
|
61
64
|
|
|
62
65
|
# compile body
|
|
63
66
|
cfg = compile_cfg(modified_block.cfg, func_builder, func_builder.inputs(), ctx)
|
{guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/decorator.py
RENAMED
|
@@ -26,7 +26,7 @@ from guppylang_internals.definition.ty import OpaqueTypeDef, TypeDef
|
|
|
26
26
|
from guppylang_internals.definition.wasm import RawWasmFunctionDef
|
|
27
27
|
from guppylang_internals.dummy_decorator import _dummy_custom_decorator, sphinx_running
|
|
28
28
|
from guppylang_internals.engine import DEF_STORE
|
|
29
|
-
from guppylang_internals.error import GuppyError
|
|
29
|
+
from guppylang_internals.error import GuppyError, pretty_errors
|
|
30
30
|
from guppylang_internals.std._internal.checker import WasmCallChecker
|
|
31
31
|
from guppylang_internals.std._internal.compiler.wasm import (
|
|
32
32
|
WasmModuleCallCompiler,
|
|
@@ -207,6 +207,7 @@ def custom_type(
|
|
|
207
207
|
return dec
|
|
208
208
|
|
|
209
209
|
|
|
210
|
+
@pretty_errors
|
|
210
211
|
def wasm_module(
|
|
211
212
|
filename: str,
|
|
212
213
|
) -> Callable[[builtins.type[T]], GuppyDefinition]:
|
|
@@ -252,6 +253,7 @@ def ext_module_decorator(
|
|
|
252
253
|
def fun(
|
|
253
254
|
filename: str, module: str | None
|
|
254
255
|
) -> Callable[[builtins.type[T]], GuppyDefinition]:
|
|
256
|
+
@pretty_errors
|
|
255
257
|
def dec(cls: builtins.type[T]) -> GuppyDefinition:
|
|
256
258
|
# N.B. Only one module per file and vice-versa
|
|
257
259
|
ext_module = type_def(
|
|
@@ -33,6 +33,7 @@ from guppylang_internals.definition.common import (
|
|
|
33
33
|
ParsableDef,
|
|
34
34
|
UnknownSourceError,
|
|
35
35
|
)
|
|
36
|
+
from guppylang_internals.definition.metadata import GuppyMetadata, add_metadata
|
|
36
37
|
from guppylang_internals.definition.value import (
|
|
37
38
|
CallableDef,
|
|
38
39
|
CallReturnWires,
|
|
@@ -72,13 +73,22 @@ class RawFunctionDef(ParsableDef):
|
|
|
72
73
|
|
|
73
74
|
unitary_flags: UnitaryFlags = field(default=UnitaryFlags.NoFlags, kw_only=True)
|
|
74
75
|
|
|
76
|
+
metadata: GuppyMetadata | None = field(default=None, kw_only=True)
|
|
77
|
+
|
|
75
78
|
def parse(self, globals: Globals, sources: SourceMap) -> "ParsedFunctionDef":
|
|
76
79
|
"""Parses and checks the user-provided signature of the function."""
|
|
77
80
|
func_ast, docstring = parse_py_func(self.python_func, sources)
|
|
78
81
|
ty = check_signature(
|
|
79
82
|
func_ast, globals, self.id, unitary_flags=self.unitary_flags
|
|
80
83
|
)
|
|
81
|
-
return ParsedFunctionDef(
|
|
84
|
+
return ParsedFunctionDef(
|
|
85
|
+
self.id,
|
|
86
|
+
self.name,
|
|
87
|
+
func_ast,
|
|
88
|
+
ty,
|
|
89
|
+
docstring,
|
|
90
|
+
metadata=self.metadata,
|
|
91
|
+
)
|
|
82
92
|
|
|
83
93
|
|
|
84
94
|
@dataclass(frozen=True)
|
|
@@ -103,6 +113,8 @@ class ParsedFunctionDef(CheckableDef, CallableDef):
|
|
|
103
113
|
|
|
104
114
|
description: str = field(default="function", init=False)
|
|
105
115
|
|
|
116
|
+
metadata: GuppyMetadata | None = field(default=None, kw_only=True)
|
|
117
|
+
|
|
106
118
|
def check(self, globals: Globals) -> "CheckedFunctionDef":
|
|
107
119
|
"""Type checks the body of the function."""
|
|
108
120
|
# Add python variable scope to the globals
|
|
@@ -114,6 +126,7 @@ class ParsedFunctionDef(CheckableDef, CallableDef):
|
|
|
114
126
|
self.ty,
|
|
115
127
|
self.docstring,
|
|
116
128
|
cfg,
|
|
129
|
+
metadata=self.metadata,
|
|
117
130
|
)
|
|
118
131
|
|
|
119
132
|
def check_call(
|
|
@@ -177,7 +190,11 @@ class CheckedFunctionDef(ParsedFunctionDef, MonomorphizableDef):
|
|
|
177
190
|
func_def = module.module_root_builder().define_function(
|
|
178
191
|
self.name, hugr_ty.body.input, hugr_ty.body.output, hugr_ty.params
|
|
179
192
|
)
|
|
180
|
-
|
|
193
|
+
add_metadata(
|
|
194
|
+
func_def,
|
|
195
|
+
self.metadata,
|
|
196
|
+
additional_metadata={"unitary": self.ty.unitary_flags.value},
|
|
197
|
+
)
|
|
181
198
|
return CompiledFunctionDef(
|
|
182
199
|
self.id,
|
|
183
200
|
self.name,
|
|
@@ -187,6 +204,7 @@ class CheckedFunctionDef(ParsedFunctionDef, MonomorphizableDef):
|
|
|
187
204
|
self.docstring,
|
|
188
205
|
self.cfg,
|
|
189
206
|
func_def,
|
|
207
|
+
metadata=self.metadata,
|
|
190
208
|
)
|
|
191
209
|
|
|
192
210
|
|
|
@@ -305,8 +323,3 @@ def parse_source(source_lines: list[str], line_offset: int) -> tuple[str, ast.AS
|
|
|
305
323
|
else:
|
|
306
324
|
node = ast.parse(source).body[0]
|
|
307
325
|
return source, node, line_offset
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def add_unitarity_metadata(func: hf.Function, flags: UnitaryFlags) -> None:
|
|
311
|
-
"""Stores unitarity annotations in the metadate of a Hugr function definition."""
|
|
312
|
-
func.metadata["unitary"] = flags.value
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Metadata attached to objects within the Guppy compiler, both for internal use and to
|
|
2
|
+
attach to HUGR nodes for lower-level processing."""
|
|
3
|
+
|
|
4
|
+
from abc import ABC
|
|
5
|
+
from dataclasses import dataclass, field, fields
|
|
6
|
+
from typing import Any, ClassVar, Generic, TypeVar
|
|
7
|
+
|
|
8
|
+
from hugr.hugr.node_port import ToNode
|
|
9
|
+
|
|
10
|
+
from guppylang_internals.diagnostic import Fatal
|
|
11
|
+
from guppylang_internals.error import GuppyError
|
|
12
|
+
|
|
13
|
+
T = TypeVar("T")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(init=True, kw_only=True)
|
|
17
|
+
class GuppyMetadataValue(ABC, Generic[T]):
|
|
18
|
+
"""A template class for a metadata value within the scope of the Guppy compiler.
|
|
19
|
+
Implementations should provide the `key` in reverse-URL format."""
|
|
20
|
+
|
|
21
|
+
key: ClassVar[str]
|
|
22
|
+
value: T | None = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MetadataMaxQubits(GuppyMetadataValue[int]):
|
|
26
|
+
key = "tket.hint.max_qubits"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True, init=True, kw_only=True)
|
|
30
|
+
class GuppyMetadata:
|
|
31
|
+
"""DTO for metadata within the scope of the guppy compiler for attachment to HUGR
|
|
32
|
+
nodes. See `add_metadata`."""
|
|
33
|
+
|
|
34
|
+
max_qubits: MetadataMaxQubits = field(default_factory=MetadataMaxQubits, init=False)
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def reserved_keys(cls) -> set[str]:
|
|
38
|
+
return {f.type.key for f in fields(GuppyMetadata)}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class MetadataAlreadySetError(Fatal):
|
|
43
|
+
title: ClassVar[str] = "Metadata key already set"
|
|
44
|
+
message: ClassVar[str] = "Received two values for the metadata key `{key}`"
|
|
45
|
+
key: str
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class ReservedMetadataKeysError(Fatal):
|
|
50
|
+
title: ClassVar[str] = "Metadata key is reserved"
|
|
51
|
+
message: ClassVar[str] = (
|
|
52
|
+
"The following metadata keys are reserved by Guppy but also provided in "
|
|
53
|
+
"additional metadata: `{keys}`"
|
|
54
|
+
)
|
|
55
|
+
keys: set[str]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def add_metadata(
|
|
59
|
+
node: ToNode,
|
|
60
|
+
metadata: GuppyMetadata | None = None,
|
|
61
|
+
*,
|
|
62
|
+
additional_metadata: dict[str, Any] | None = None,
|
|
63
|
+
) -> None:
|
|
64
|
+
"""Adds metadata to the given node using the keys defined through inheritors of
|
|
65
|
+
`GuppyMetadataValue` defined in the `GuppyMetadata` class.
|
|
66
|
+
|
|
67
|
+
Additional metadata is forwarded as is, although the given dictionary may not
|
|
68
|
+
contain any keys already reserved by fields in `GuppyMetadata`.
|
|
69
|
+
"""
|
|
70
|
+
if metadata is not None:
|
|
71
|
+
for f in fields(GuppyMetadata):
|
|
72
|
+
data: GuppyMetadataValue[Any] = getattr(metadata, f.name)
|
|
73
|
+
if data.key in node.metadata:
|
|
74
|
+
raise GuppyError(MetadataAlreadySetError(None, data.key))
|
|
75
|
+
if data.value is not None:
|
|
76
|
+
node.metadata[data.key] = data.value
|
|
77
|
+
|
|
78
|
+
if additional_metadata is not None:
|
|
79
|
+
reserved_keys = GuppyMetadata.reserved_keys()
|
|
80
|
+
used_reserved_keys = reserved_keys.intersection(additional_metadata.keys())
|
|
81
|
+
if len(used_reserved_keys) > 0:
|
|
82
|
+
raise GuppyError(ReservedMetadataKeysError(None, keys=used_reserved_keys))
|
|
83
|
+
|
|
84
|
+
for key, value in additional_metadata.items():
|
|
85
|
+
if key in node.metadata:
|
|
86
|
+
raise GuppyError(MetadataAlreadySetError(None, key))
|
|
87
|
+
node.metadata[key] = value
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
+
import copy
|
|
2
3
|
from contextlib import suppress
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
5
|
from typing import ClassVar, NoReturn
|
|
@@ -86,7 +87,11 @@ class OverloadedFunctionDef(CompiledCallableDef, CallableDef):
|
|
|
86
87
|
assert isinstance(defn, CallableDef)
|
|
87
88
|
available_sigs.append(defn.ty)
|
|
88
89
|
with suppress(GuppyError):
|
|
89
|
-
|
|
90
|
+
# check_call may modify args and node,
|
|
91
|
+
# thus we deepcopy them before passing in the function
|
|
92
|
+
node_copy = copy.deepcopy(node)
|
|
93
|
+
args_copy = copy.deepcopy(args)
|
|
94
|
+
return defn.check_call(args_copy, ty, node_copy, ctx)
|
|
90
95
|
return self._call_error(args, node, ctx, available_sigs, ty)
|
|
91
96
|
|
|
92
97
|
def synthesize_call(
|
|
@@ -98,7 +103,11 @@ class OverloadedFunctionDef(CompiledCallableDef, CallableDef):
|
|
|
98
103
|
assert isinstance(defn, CallableDef)
|
|
99
104
|
available_sigs.append(defn.ty)
|
|
100
105
|
with suppress(GuppyError):
|
|
101
|
-
|
|
106
|
+
# synthesize_call may modify args and node,
|
|
107
|
+
# thus we deepcopy them before passing in the function
|
|
108
|
+
node_copy = copy.deepcopy(node)
|
|
109
|
+
args_copy = copy.deepcopy(args)
|
|
110
|
+
return defn.synthesize_call(args_copy, node_copy, ctx)
|
|
102
111
|
return self._call_error(args, node, ctx, available_sigs)
|
|
103
112
|
|
|
104
113
|
def _call_error(
|
|
@@ -46,6 +46,7 @@ from guppylang_internals.std._internal.compiler.array import (
|
|
|
46
46
|
array_new,
|
|
47
47
|
array_unpack,
|
|
48
48
|
)
|
|
49
|
+
from guppylang_internals.std._internal.compiler.quantum import from_halfturns_unchecked
|
|
49
50
|
from guppylang_internals.std._internal.compiler.tket_bool import OpaqueBool, make_opaque
|
|
50
51
|
from guppylang_internals.tys.builtin import array_type, bool_type, float_type
|
|
51
52
|
from guppylang_internals.tys.subst import Inst, Subst
|
|
@@ -235,12 +236,15 @@ class ParsedPytketDef(CallableDef, CompilableDef):
|
|
|
235
236
|
lex_names = sorted(param_order)
|
|
236
237
|
name_to_param = dict(zip(lex_names, lex_params, strict=True))
|
|
237
238
|
angle_wires = [name_to_param[name] for name in param_order]
|
|
238
|
-
# Need to convert all angles to
|
|
239
|
+
# Need to convert all angles to rotations.
|
|
239
240
|
for angle in angle_wires:
|
|
240
241
|
[halfturns] = outer_func.add_op(
|
|
241
242
|
ops.UnpackTuple([FLOAT_T]), angle
|
|
242
243
|
)
|
|
243
|
-
|
|
244
|
+
rotation = outer_func.add_op(
|
|
245
|
+
from_halfturns_unchecked(), halfturns
|
|
246
|
+
)
|
|
247
|
+
param_wires.append(rotation)
|
|
244
248
|
|
|
245
249
|
# Pass all arguments to call node.
|
|
246
250
|
call_node = outer_func.call(
|
{guppylang_internals-0.26.0 → guppylang_internals-0.27.0}/src/guppylang_internals/diagnostic.py
RENAMED
|
@@ -208,7 +208,8 @@ class DiagnosticsRenderer:
|
|
|
208
208
|
MAX_MESSAGE_LINE_LEN: Final[int] = 80
|
|
209
209
|
|
|
210
210
|
#: Number of preceding source lines we show to give additional context
|
|
211
|
-
|
|
211
|
+
PREFIX_ERROR_CONTEXT_LINES: Final[int] = 2
|
|
212
|
+
PREFIX_NOTE_CONTEXT_LINES: Final[int] = 1
|
|
212
213
|
|
|
213
214
|
def __init__(self, source: SourceMap) -> None:
|
|
214
215
|
self.buffer = []
|
|
@@ -243,31 +244,84 @@ class DiagnosticsRenderer:
|
|
|
243
244
|
else:
|
|
244
245
|
span = to_span(diag.span)
|
|
245
246
|
level = self.level_str(diag.level)
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
|
|
248
|
+
children_with_span = [
|
|
249
|
+
(child, to_span(child.span)) for child in diag.children if child.span
|
|
248
250
|
]
|
|
251
|
+
all_spans = [span] + [span for _, span in children_with_span]
|
|
249
252
|
max_lineno = max(s.end.line for s in all_spans)
|
|
253
|
+
|
|
250
254
|
self.buffer.append(f"{level}: {diag.rendered_title} (at {span.start})")
|
|
255
|
+
|
|
256
|
+
# Render main error span first
|
|
251
257
|
self.render_snippet(
|
|
252
258
|
span,
|
|
253
259
|
diag.rendered_span_label,
|
|
254
260
|
max_lineno,
|
|
255
261
|
is_primary=True,
|
|
256
|
-
prefix_lines=self.
|
|
262
|
+
prefix_lines=self.PREFIX_ERROR_CONTEXT_LINES,
|
|
257
263
|
)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
264
|
+
|
|
265
|
+
match children_with_span:
|
|
266
|
+
case []:
|
|
267
|
+
pass
|
|
268
|
+
case [(only_child, span)]:
|
|
269
|
+
self.buffer.append("\nNote:")
|
|
261
270
|
self.render_snippet(
|
|
262
|
-
|
|
263
|
-
|
|
271
|
+
span,
|
|
272
|
+
only_child.rendered_span_label,
|
|
264
273
|
max_lineno,
|
|
265
|
-
|
|
274
|
+
prefix_lines=self.PREFIX_NOTE_CONTEXT_LINES,
|
|
275
|
+
print_pad_line=True,
|
|
266
276
|
)
|
|
277
|
+
case [(first_child, first_span), *children_with_span]:
|
|
278
|
+
self.buffer.append("\nNotes:")
|
|
279
|
+
self.render_snippet(
|
|
280
|
+
first_span,
|
|
281
|
+
first_child.rendered_span_label,
|
|
282
|
+
max_lineno,
|
|
283
|
+
prefix_lines=self.PREFIX_NOTE_CONTEXT_LINES,
|
|
284
|
+
print_pad_line=True,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
prev_span_end_lineno = first_span.end.line
|
|
288
|
+
|
|
289
|
+
for sub_diag, span in children_with_span:
|
|
290
|
+
span_start_lineno = span.start.line
|
|
291
|
+
span_end_lineno = span.end.line
|
|
292
|
+
|
|
293
|
+
# If notes are on the same line, render them together
|
|
294
|
+
if span_start_lineno == prev_span_end_lineno:
|
|
295
|
+
prefix_lines = 0
|
|
296
|
+
print_pad_line = True
|
|
297
|
+
# if notes are close enough, render them adjacently
|
|
298
|
+
elif (
|
|
299
|
+
span_start_lineno - self.PREFIX_NOTE_CONTEXT_LINES
|
|
300
|
+
<= prev_span_end_lineno + 1
|
|
301
|
+
):
|
|
302
|
+
prefix_lines = span_start_lineno - prev_span_end_lineno - 1
|
|
303
|
+
print_pad_line = False
|
|
304
|
+
# otherwise we render a separator between notes
|
|
305
|
+
else:
|
|
306
|
+
self.buffer.append("")
|
|
307
|
+
prefix_lines = self.PREFIX_NOTE_CONTEXT_LINES
|
|
308
|
+
print_pad_line = False
|
|
309
|
+
|
|
310
|
+
self.render_snippet(
|
|
311
|
+
span,
|
|
312
|
+
sub_diag.rendered_span_label,
|
|
313
|
+
max_lineno,
|
|
314
|
+
prefix_lines=prefix_lines,
|
|
315
|
+
print_pad_line=print_pad_line,
|
|
316
|
+
)
|
|
317
|
+
prev_span_end_lineno = span_end_lineno
|
|
318
|
+
|
|
319
|
+
# Render the main diagnostic message if present
|
|
267
320
|
if diag.rendered_message:
|
|
268
321
|
self.buffer.append("")
|
|
269
322
|
self.buffer += wrap(diag.rendered_message, self.MAX_MESSAGE_LINE_LEN)
|
|
270
|
-
|
|
323
|
+
|
|
324
|
+
# Render all sub-diagnostics that have a non-span message
|
|
271
325
|
for sub_diag in diag.children:
|
|
272
326
|
if sub_diag.rendered_message:
|
|
273
327
|
self.buffer.append("")
|
|
@@ -281,8 +335,9 @@ class DiagnosticsRenderer:
|
|
|
281
335
|
span: Span,
|
|
282
336
|
label: str | None,
|
|
283
337
|
max_lineno: int,
|
|
284
|
-
is_primary: bool,
|
|
338
|
+
is_primary: bool = False,
|
|
285
339
|
prefix_lines: int = 0,
|
|
340
|
+
print_pad_line: bool = False,
|
|
286
341
|
) -> None:
|
|
287
342
|
"""Renders the source associated with a span together with an optional label.
|
|
288
343
|
|
|
@@ -315,7 +370,8 @@ class DiagnosticsRenderer:
|
|
|
315
370
|
Optionally includes up to `prefix_lines` preceding source lines to give
|
|
316
371
|
additional context.
|
|
317
372
|
"""
|
|
318
|
-
# Check how much space we need to reserve for the leading
|
|
373
|
+
# Check how much horizontal space we need to reserve for the leading
|
|
374
|
+
# line numbers
|
|
319
375
|
ll_length = len(str(max_lineno))
|
|
320
376
|
highlight_char = "^" if is_primary else "-"
|
|
321
377
|
|
|
@@ -324,8 +380,9 @@ class DiagnosticsRenderer:
|
|
|
324
380
|
ll = "" if line_number is None else str(line_number)
|
|
325
381
|
self.buffer.append(" " * (ll_length - len(ll)) + ll + " | " + line)
|
|
326
382
|
|
|
327
|
-
# One line of padding
|
|
328
|
-
|
|
383
|
+
# One line of padding (primary span, first note or between same line notes)
|
|
384
|
+
if is_primary or print_pad_line:
|
|
385
|
+
render_line("")
|
|
329
386
|
|
|
330
387
|
# Grab all lines we want to display and remove excessive leading whitespace
|
|
331
388
|
prefix_lines = min(prefix_lines, span.start.line - 1)
|
|
@@ -220,21 +220,12 @@ class CompilationEngine:
|
|
|
220
220
|
|
|
221
221
|
This is the main driver behind `guppy.check()`.
|
|
222
222
|
"""
|
|
223
|
-
from guppylang_internals.checker.core import Globals
|
|
224
|
-
|
|
225
223
|
# Clear previous compilation cache.
|
|
226
224
|
# TODO: In order to maintain results from the previous `check` call we would
|
|
227
225
|
# need to store and check if any dependencies have changed.
|
|
228
226
|
self.reset()
|
|
229
227
|
|
|
230
|
-
|
|
231
|
-
self.to_check_worklist = {
|
|
232
|
-
defn.id: (
|
|
233
|
-
defn.parse(Globals(DEF_STORE.frames[defn.id]), DEF_STORE.sources)
|
|
234
|
-
if isinstance(defn, ParsableDef)
|
|
235
|
-
else defn
|
|
236
|
-
)
|
|
237
|
-
}
|
|
228
|
+
self.to_check_worklist[id] = self.get_parsed(id)
|
|
238
229
|
while self.types_to_check_worklist or self.to_check_worklist:
|
|
239
230
|
# Types need to be checked first. This is because parsing e.g. a function
|
|
240
231
|
# definition requires instantiating the types in its signature which can
|