guppylang-internals 0.26.0__tar.gz → 0.28.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.28.0}/CHANGELOG.md +52 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/PKG-INFO +5 -4
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/pyproject.toml +6 -7
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/__init__.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/ast_util.py +37 -18
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/analysis.py +6 -6
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/builder.py +44 -12
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/cfg.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/core.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/comptime_errors.py +0 -12
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/linearity.py +6 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/expr_checker.py +53 -28
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/func_checker.py +4 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/stmt_checker.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/cfg_compiler.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/core.py +17 -4
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/expr_compiler.py +36 -14
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/modifier_compiler.py +5 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/decorator.py +5 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/common.py +1 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/custom.py +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/declaration.py +3 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/function.py +28 -8
- guppylang_internals-0.28.0/src/guppylang_internals/definition/metadata.py +87 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/overloaded.py +11 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/pytket_circuits.py +50 -67
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/value.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/wasm.py +3 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/diagnostic.py +89 -16
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/engine.py +84 -40
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/error.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/nodes.py +301 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/span.py +7 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/checker.py +104 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/array.py +36 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/either.py +14 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/tket_bool.py +1 -6
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/tket_exts.py +1 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/debug.py +5 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/builtins_mock.py +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/object.py +6 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/parsing.py +4 -1
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/qubit.py +6 -4
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/subst.py +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/ty.py +2 -2
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/wasm_util.py +2 -3
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/.gitignore +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/LICENCE +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/README.md +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/bb.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/cfg_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/generic.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/type_errors.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/errors/wasm.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/linearity_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/modifier_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/unitary_checker.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/func_compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/hugr_extension.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/qtm_platform_extension.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/compiler/stmt_compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/const.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/extern.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/parameter.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/struct.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/traced.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/definition/ty.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/dummy_decorator.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/experimental.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/ipython_inspect.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/py.typed +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/arithmetic.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/frozenarray.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/futures.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/list.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/mem.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/option.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/platform.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/prelude.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/qsystem.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/quantum.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler/wasm.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/compiler.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/std/_internal/util.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/frozenlist.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/function.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/state.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/unpacking.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tracing/util.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/__init__.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/arg.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/builtin.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/common.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/const.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/errors.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/param.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/printing.py +0 -0
- {guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/tys/var.py +0 -0
|
@@ -3,6 +3,58 @@
|
|
|
3
3
|
First release of `guppylang_internals` package containing refactored out internal components
|
|
4
4
|
from `guppylang`.
|
|
5
5
|
|
|
6
|
+
## [0.28.0](https://github.com/Quantinuum/guppylang/compare/guppylang-internals-v0.27.0...guppylang-internals-v0.28.0) (2026-02-04)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### ⚠ BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* Tket is now a non-optional dependency. Most systems already have this installed, rerunning the package manager should fix any issues.
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* Label `FuncDefn`s with qualified names in HUGR ([#1452](https://github.com/Quantinuum/guppylang/issues/1452)) ([a92f274](https://github.com/Quantinuum/guppylang/commit/a92f274a14668b7ac88713a69a6902aca62d4483))
|
|
16
|
+
* Make tket a non-optional dependency ([#1440](https://github.com/Quantinuum/guppylang/issues/1440)) ([4af4360](https://github.com/Quantinuum/guppylang/commit/4af4360495c9d6155e69310d5bfb8f22953fc1ff))
|
|
17
|
+
* use hugr used_extensions in engine.py ([#1451](https://github.com/Quantinuum/guppylang/issues/1451)) ([c16b96b](https://github.com/Quantinuum/guppylang/commit/c16b96bd5dc6ab4df13e3242ffe55279b317dd7e))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* Add a copy before fallable `synthesize_call` call ([#1460](https://github.com/Quantinuum/guppylang/issues/1460)) ([84137c3](https://github.com/Quantinuum/guppylang/commit/84137c39b7e8ca24142ffe73afcce6a1bcceffe2))
|
|
23
|
+
* Raise type inference error when not all function argument types could be resolved. ([#1439](https://github.com/Quantinuum/guppylang/issues/1439)) ([4120d59](https://github.com/Quantinuum/guppylang/commit/4120d590917245258d69ceb07c763c7633c7c5f8)), closes [#1437](https://github.com/Quantinuum/guppylang/issues/1437)
|
|
24
|
+
* Remove leading tab characters from diagnostics during rendering ([#1447](https://github.com/Quantinuum/guppylang/issues/1447)) ([a1cf792](https://github.com/Quantinuum/guppylang/commit/a1cf792deaf90e31721505ac17fd4911737e6c26)), closes [#1101](https://github.com/Quantinuum/guppylang/issues/1101)
|
|
25
|
+
* Support comptime expressions in subscript assignments ([#1433](https://github.com/Quantinuum/guppylang/issues/1433)) ([108c104](https://github.com/Quantinuum/guppylang/commit/108c104d55ecb052d4d7c363062f444efc689724)), closes [#1363](https://github.com/Quantinuum/guppylang/issues/1363)
|
|
26
|
+
* Support more cases of comptime subscripts ([#1436](https://github.com/Quantinuum/guppylang/issues/1436)) ([9aefdcc](https://github.com/Quantinuum/guppylang/commit/9aefdcc50b142acf842cf60314b5bccc49e01614)), closes [#1435](https://github.com/Quantinuum/guppylang/issues/1435)
|
|
27
|
+
|
|
28
|
+
## [0.27.0](https://github.com/Quantinuum/guppylang/compare/guppylang-internals-v0.26.0...guppylang-internals-v0.27.0) (2026-01-08)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### ⚠ BREAKING CHANGES
|
|
32
|
+
|
|
33
|
+
* The first argument to `add_unitarity_metadata` is now named `node`
|
|
34
|
+
instead of `func`, since its type was raised to allow for more HUGR
|
|
35
|
+
nodes to be fed. Migration is trivial.
|
|
36
|
+
* `DiagnosticsRenderer.PREFIX_CONTEXT_LINES` constant has been removed.
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* 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)
|
|
41
|
+
* Add unsafe array take and put operations ([#1165](https://github.com/Quantinuum/guppylang/issues/1165)) ([7f342e7](https://github.com/Quantinuum/guppylang/commit/7f342e788e2f179382bab46dcc7e69a24dd64de3))
|
|
42
|
+
* **internals:** update to hugr-py 0.15 ([#1418](https://github.com/Quantinuum/guppylang/issues/1418)) ([cf970ba](https://github.com/Quantinuum/guppylang/commit/cf970ba7403a126fbd5d2fd53445e65270581df4))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Bug Fixes
|
|
46
|
+
|
|
47
|
+
* Add a line break for printing WASM files ([#1386](https://github.com/Quantinuum/guppylang/issues/1386)) ([495aba5](https://github.com/Quantinuum/guppylang/commit/495aba5b9bb2218224193c7b2da2c5586744505a))
|
|
48
|
+
* added deepcopy in `OverloadedFunctionDef.{check_call,synthesize_call}` ([#1426](https://github.com/Quantinuum/guppylang/issues/1426)) ([9be6fef](https://github.com/Quantinuum/guppylang/commit/9be6fefcdfb9fc9eb1025774d2dd2727b3e719b1))
|
|
49
|
+
* **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))
|
|
50
|
+
* Convert symbolic pytket circuits angle inputs into rotations ([#1425](https://github.com/Quantinuum/guppylang/issues/1425)) ([4724d90](https://github.com/Quantinuum/guppylang/commit/4724d9039d8dffae8fd939f62ae80ec307d8918a))
|
|
51
|
+
* 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)
|
|
52
|
+
* Fix another wasm diagnostics rendering issue ([#1399](https://github.com/Quantinuum/guppylang/issues/1399)) ([6604175](https://github.com/Quantinuum/guppylang/commit/660417542f2b36c387e73765f8647c11cd3d1a7b))
|
|
53
|
+
* 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)
|
|
54
|
+
* improve diagnostics rendering ([#1382](https://github.com/Quantinuum/guppylang/issues/1382)) ([e7ce7f6](https://github.com/Quantinuum/guppylang/commit/e7ce7f6d1a4f2b12ff680a6e54dae96637c5fa92))
|
|
55
|
+
* Stop parsing entrypoints twice ([#1410](https://github.com/Quantinuum/guppylang/issues/1410)) ([4a167e5](https://github.com/Quantinuum/guppylang/commit/4a167e5642cedc8f47ad027ed08483caa1558830))
|
|
56
|
+
* 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)
|
|
57
|
+
|
|
6
58
|
## [0.26.0](https://github.com/Quantinuum/guppylang/compare/guppylang-internals-v0.25.0...guppylang-internals-v0.26.0) (2025-12-11)
|
|
7
59
|
|
|
8
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guppylang-internals
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28.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,12 +219,13 @@ 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.1
|
|
223
|
+
Requires-Dist: pytket>=1.34
|
|
223
224
|
Requires-Dist: tket-exts~=0.12.0
|
|
225
|
+
Requires-Dist: tket>=0.12.7
|
|
224
226
|
Requires-Dist: typing-extensions<5,>=4.9.0
|
|
225
|
-
Requires-Dist: wasmtime
|
|
227
|
+
Requires-Dist: wasmtime<41.1,>=38.0
|
|
226
228
|
Provides-Extra: pytket
|
|
227
|
-
Requires-Dist: pytket>=1.34; extra == 'pytket'
|
|
228
229
|
Description-Content-Type: text/markdown
|
|
229
230
|
|
|
230
231
|
# guppylang-internals
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "guppylang-internals"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.28.0"
|
|
4
4
|
requires-python = ">=3.10,<4"
|
|
5
5
|
description = "Compiler internals for `guppylang` package."
|
|
6
6
|
license = { file = "LICENCE" }
|
|
@@ -16,13 +16,10 @@ maintainers = [
|
|
|
16
16
|
|
|
17
17
|
classifiers = [
|
|
18
18
|
"Development Status :: 3 - Alpha",
|
|
19
|
-
|
|
20
19
|
"Intended Audience :: Developers",
|
|
21
20
|
"Intended Audience :: Science/Research",
|
|
22
21
|
"Topic :: Software Development :: Compilers",
|
|
23
|
-
|
|
24
22
|
"License :: OSI Approved :: Apache Software License",
|
|
25
|
-
|
|
26
23
|
"Programming Language :: Python :: 3",
|
|
27
24
|
"Programming Language :: Python :: 3.10",
|
|
28
25
|
"Programming Language :: Python :: 3.11",
|
|
@@ -35,12 +32,14 @@ classifiers = [
|
|
|
35
32
|
dependencies = [
|
|
36
33
|
"typing-extensions >=4.9.0,<5",
|
|
37
34
|
"tket-exts ~= 0.12.0",
|
|
38
|
-
"hugr ~= 0.
|
|
39
|
-
"wasmtime
|
|
35
|
+
"hugr ~= 0.15.1",
|
|
36
|
+
"wasmtime>=38.0,<41.1",
|
|
37
|
+
"pytket>=1.34",
|
|
38
|
+
"tket >= 0.12.7",
|
|
40
39
|
]
|
|
41
40
|
|
|
42
41
|
[project.optional-dependencies]
|
|
43
|
-
pytket = [
|
|
42
|
+
pytket = []
|
|
44
43
|
|
|
45
44
|
[build-system]
|
|
46
45
|
requires = ["hatchling"]
|
{guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/ast_util.py
RENAMED
|
@@ -97,13 +97,13 @@ def find_nodes(
|
|
|
97
97
|
def name_nodes_in_ast(node: Any) -> list[ast.Name]:
|
|
98
98
|
"""Returns all `Name` nodes occurring in an AST."""
|
|
99
99
|
found = find_nodes(lambda n: isinstance(n, ast.Name), node)
|
|
100
|
-
return cast(list[ast.Name], found)
|
|
100
|
+
return cast("list[ast.Name]", found)
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def return_nodes_in_ast(node: Any) -> list[ast.Return]:
|
|
104
104
|
"""Returns all `Return` nodes occurring in an AST."""
|
|
105
105
|
found = find_nodes(lambda n: isinstance(n, ast.Return), node, {ast.FunctionDef})
|
|
106
|
-
return cast(list[ast.Return], found)
|
|
106
|
+
return cast("list[ast.Return]", found)
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def loop_in_ast(node: Any) -> list[ast.For | ast.While]:
|
|
@@ -111,7 +111,7 @@ def loop_in_ast(node: Any) -> list[ast.For | ast.While]:
|
|
|
111
111
|
found = find_nodes(
|
|
112
112
|
lambda n: isinstance(n, ast.For | ast.While), node, {ast.FunctionDef}
|
|
113
113
|
)
|
|
114
|
-
return cast(list[ast.For | ast.While], found)
|
|
114
|
+
return cast("list[ast.For | ast.While]", found)
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
def breaks_in_loop(node: Any) -> list[ast.Break]:
|
|
@@ -122,7 +122,7 @@ def breaks_in_loop(node: Any) -> list[ast.Break]:
|
|
|
122
122
|
found = find_nodes(
|
|
123
123
|
lambda n: isinstance(n, ast.Break), node, {ast.For, ast.While, ast.FunctionDef}
|
|
124
124
|
)
|
|
125
|
-
return cast(list[ast.Break], found)
|
|
125
|
+
return cast("list[ast.Break]", found)
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
def loop_controls_in_loop(node: Any) -> list[ast.Break | ast.Continue]:
|
|
@@ -135,7 +135,7 @@ def loop_controls_in_loop(node: Any) -> list[ast.Break | ast.Continue]:
|
|
|
135
135
|
node,
|
|
136
136
|
{ast.For, ast.While, ast.FunctionDef},
|
|
137
137
|
)
|
|
138
|
-
return cast(list[ast.Break | ast.Continue], found)
|
|
138
|
+
return cast("list[ast.Break | ast.Continue]", found)
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
class ContextAdjuster(ast.NodeTransformer):
|
|
@@ -147,7 +147,7 @@ class ContextAdjuster(ast.NodeTransformer):
|
|
|
147
147
|
self.ctx = ctx
|
|
148
148
|
|
|
149
149
|
def visit(self, node: ast.AST) -> ast.AST:
|
|
150
|
-
return cast(ast.AST, super().visit(node))
|
|
150
|
+
return cast("ast.AST", super().visit(node))
|
|
151
151
|
|
|
152
152
|
def visit_Name(self, node: ast.Name) -> ast.Name:
|
|
153
153
|
return with_loc(node, ast.Name(id=node.id, ctx=self.ctx))
|
|
@@ -156,29 +156,48 @@ class ContextAdjuster(ast.NodeTransformer):
|
|
|
156
156
|
self,
|
|
157
157
|
node: ast.Starred,
|
|
158
158
|
) -> ast.Starred:
|
|
159
|
-
return with_loc(
|
|
159
|
+
return with_loc(
|
|
160
|
+
node,
|
|
161
|
+
ast.Starred(value=self.visit(node.value), ctx=self.ctx), # type: ignore[arg-type]
|
|
162
|
+
)
|
|
160
163
|
|
|
161
164
|
def visit_Tuple(self, node: ast.Tuple) -> ast.Tuple:
|
|
162
165
|
return with_loc(
|
|
163
|
-
node,
|
|
166
|
+
node,
|
|
167
|
+
ast.Tuple(
|
|
168
|
+
elts=[self.visit(elt) for elt in node.elts], # type: ignore[misc]
|
|
169
|
+
ctx=self.ctx,
|
|
170
|
+
),
|
|
164
171
|
)
|
|
165
172
|
|
|
166
173
|
def visit_List(self, node: ast.List) -> ast.List:
|
|
167
174
|
return with_loc(
|
|
168
|
-
node,
|
|
175
|
+
node,
|
|
176
|
+
ast.List(
|
|
177
|
+
elts=[self.visit(elt) for elt in node.elts], # type: ignore[misc]
|
|
178
|
+
ctx=self.ctx,
|
|
179
|
+
),
|
|
169
180
|
)
|
|
170
181
|
|
|
171
182
|
def visit_Subscript(self, node: ast.Subscript) -> ast.Subscript:
|
|
172
183
|
# Don't adjust the slice!
|
|
173
184
|
return with_loc(
|
|
174
185
|
node,
|
|
175
|
-
ast.Subscript(
|
|
186
|
+
ast.Subscript(
|
|
187
|
+
value=self.visit(node.value), # type: ignore[arg-type]
|
|
188
|
+
slice=node.slice,
|
|
189
|
+
ctx=self.ctx,
|
|
190
|
+
),
|
|
176
191
|
)
|
|
177
192
|
|
|
178
193
|
def visit_Attribute(self, node: ast.Attribute) -> ast.Attribute:
|
|
179
194
|
return with_loc(
|
|
180
195
|
node,
|
|
181
|
-
ast.Attribute(
|
|
196
|
+
ast.Attribute(
|
|
197
|
+
value=self.visit(node.value), # type: ignore[arg-type]
|
|
198
|
+
attr=node.attr,
|
|
199
|
+
ctx=self.ctx,
|
|
200
|
+
),
|
|
182
201
|
)
|
|
183
202
|
|
|
184
203
|
|
|
@@ -240,15 +259,15 @@ def template_replace(
|
|
|
240
259
|
|
|
241
260
|
def line_col(node: ast.AST) -> tuple[int, int]:
|
|
242
261
|
"""Returns the line and column of an ast node."""
|
|
243
|
-
return node.lineno, node.col_offset
|
|
262
|
+
return node.lineno, node.col_offset # type: ignore[attr-defined]
|
|
244
263
|
|
|
245
264
|
|
|
246
265
|
def set_location_from(node: ast.AST, loc: ast.AST) -> None:
|
|
247
266
|
"""Copy source location from one AST node to the other."""
|
|
248
|
-
node.lineno = loc.lineno
|
|
249
|
-
node.col_offset = loc.col_offset
|
|
250
|
-
node.end_lineno = loc.end_lineno
|
|
251
|
-
node.end_col_offset = loc.end_col_offset
|
|
267
|
+
node.lineno = loc.lineno # type: ignore[attr-defined]
|
|
268
|
+
node.col_offset = loc.col_offset # type: ignore[attr-defined]
|
|
269
|
+
node.end_lineno = loc.end_lineno # type: ignore[attr-defined]
|
|
270
|
+
node.end_col_offset = loc.end_col_offset # type: ignore[attr-defined]
|
|
252
271
|
|
|
253
272
|
source, file, line_offset = get_source(loc), get_file(loc), get_line_offset(loc)
|
|
254
273
|
assert source is not None
|
|
@@ -341,11 +360,11 @@ def with_type(ty: "Type", node: A) -> A:
|
|
|
341
360
|
|
|
342
361
|
def get_type_opt(node: AstNode) -> Optional["Type"]:
|
|
343
362
|
"""Tries to retrieve a type annotation from an AST node."""
|
|
344
|
-
from guppylang_internals.tys.ty import
|
|
363
|
+
from guppylang_internals.tys.ty import TypeBase
|
|
345
364
|
|
|
346
365
|
try:
|
|
347
366
|
ty = node.type # type: ignore[union-attr]
|
|
348
|
-
return cast(Type, ty) if isinstance(ty, TypeBase) else None
|
|
367
|
+
return cast("Type", ty) if isinstance(ty, TypeBase) else None
|
|
349
368
|
except AttributeError:
|
|
350
369
|
return None
|
|
351
370
|
|
{guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/analysis.py
RENAMED
|
@@ -11,7 +11,7 @@ T = TypeVar("T")
|
|
|
11
11
|
Result = dict[BB, T]
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class Analysis(Generic[T]
|
|
14
|
+
class Analysis(ABC, Generic[T]):
|
|
15
15
|
"""Abstract base class for a program analysis pass over the lattice `T`"""
|
|
16
16
|
|
|
17
17
|
def eq(self, t1: T, t2: T, /) -> bool:
|
|
@@ -39,7 +39,7 @@ class Analysis(Generic[T], ABC):
|
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class ForwardAnalysis(
|
|
42
|
+
class ForwardAnalysis(Analysis[T], ABC, Generic[T]):
|
|
43
43
|
"""Abstract base class for a program analysis pass running in forward direction."""
|
|
44
44
|
|
|
45
45
|
@abstractmethod
|
|
@@ -71,7 +71,7 @@ class ForwardAnalysis(Generic[T], Analysis[T], ABC):
|
|
|
71
71
|
return vals_before
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
class BackwardAnalysis(
|
|
74
|
+
class BackwardAnalysis(Analysis[T], ABC, Generic[T]):
|
|
75
75
|
"""Abstract base class for a program analysis pass running in backward direction."""
|
|
76
76
|
|
|
77
77
|
@abstractmethod
|
|
@@ -105,7 +105,7 @@ class BackwardAnalysis(Generic[T], Analysis[T], ABC):
|
|
|
105
105
|
LivenessDomain = dict[VId, BB]
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
class LivenessAnalysis(
|
|
108
|
+
class LivenessAnalysis(BackwardAnalysis[LivenessDomain[VId]], Generic[VId]):
|
|
109
109
|
"""Live variable analysis pass.
|
|
110
110
|
|
|
111
111
|
Computes the variables that are live before the execution of each BB. The analysis
|
|
@@ -143,7 +143,7 @@ class LivenessAnalysis(Generic[VId], BackwardAnalysis[LivenessDomain[VId]]):
|
|
|
143
143
|
|
|
144
144
|
def apply_bb(self, live_after: LivenessDomain[VId], bb: BB) -> LivenessDomain[VId]:
|
|
145
145
|
stats = self.stats[bb]
|
|
146
|
-
return
|
|
146
|
+
return dict.fromkeys(stats.used, bb) | {
|
|
147
147
|
x: b for x, b in live_after.items() if x not in stats.assigned
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -159,7 +159,7 @@ MaybeAssignmentDomain = set[VId]
|
|
|
159
159
|
AssignmentDomain = tuple[DefAssignmentDomain[VId], MaybeAssignmentDomain[VId]]
|
|
160
160
|
|
|
161
161
|
|
|
162
|
-
class AssignmentAnalysis(
|
|
162
|
+
class AssignmentAnalysis(ForwardAnalysis[AssignmentDomain[VId]], Generic[VId]):
|
|
163
163
|
"""Assigned variable analysis pass.
|
|
164
164
|
|
|
165
165
|
Computes the set of variables (i.e. `V`s) that are definitely assigned at the start
|
{guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/builder.py
RENAMED
|
@@ -154,27 +154,52 @@ class CFGBuilder(AstVisitor[BB | None]):
|
|
|
154
154
|
return bb_opt
|
|
155
155
|
|
|
156
156
|
def _build_node_value(self, node: BBStatement, bb: BB) -> BB:
|
|
157
|
-
"""Utility method for building a
|
|
157
|
+
"""Utility method for building a nodes `value` expression, if available.
|
|
158
158
|
|
|
159
159
|
Builds the expression and mutates `node.value` to point to the built expression.
|
|
160
|
-
Returns the BB in which the expression is available
|
|
160
|
+
Returns the BB in which the expression is available.
|
|
161
161
|
"""
|
|
162
162
|
if (
|
|
163
163
|
not isinstance(node, NestedFunctionDef | ModifiedBlock)
|
|
164
164
|
and node.value is not None
|
|
165
165
|
):
|
|
166
166
|
node.value, bb = ExprBuilder.build(node.value, self.cfg, bb)
|
|
167
|
-
bb
|
|
167
|
+
return bb
|
|
168
|
+
|
|
169
|
+
def _build_node_targets(self, node: BBStatement, bb: BB) -> BB:
|
|
170
|
+
"""Utility method for building a nodes `target` or `targets` expressions,
|
|
171
|
+
depending on the node type.
|
|
172
|
+
|
|
173
|
+
Builds the expressions and mutates the elements of `node.targets` to point to
|
|
174
|
+
the built expressions. Returns the BB in which the expressions are available.
|
|
175
|
+
"""
|
|
176
|
+
if isinstance(node, ast.Assign):
|
|
177
|
+
for i, target in enumerate(node.targets):
|
|
178
|
+
node.targets[i], bb = ExprBuilder.build(target, self.cfg, bb)
|
|
179
|
+
elif isinstance(node, ast.AugAssign | ast.AnnAssign):
|
|
180
|
+
new_target, bb = ExprBuilder.build(node.target, self.cfg, bb)
|
|
181
|
+
if not isinstance(new_target, ast.Name | ast.Attribute | ast.Subscript):
|
|
182
|
+
raise InternalGuppyError("Unexpected type for built expression.")
|
|
183
|
+
node.target = new_target
|
|
168
184
|
return bb
|
|
169
185
|
|
|
170
186
|
def visit_Assign(self, node: ast.Assign, bb: BB, jumps: Jumps) -> BB | None:
|
|
171
|
-
|
|
187
|
+
bb = self._build_node_value(node, bb)
|
|
188
|
+
bb = self._build_node_targets(node, bb)
|
|
189
|
+
bb.statements.append(node)
|
|
190
|
+
return bb
|
|
172
191
|
|
|
173
192
|
def visit_AugAssign(self, node: ast.AugAssign, bb: BB, jumps: Jumps) -> BB | None:
|
|
174
|
-
|
|
193
|
+
bb = self._build_node_value(node, bb)
|
|
194
|
+
bb = self._build_node_targets(node, bb)
|
|
195
|
+
bb.statements.append(node)
|
|
196
|
+
return bb
|
|
175
197
|
|
|
176
198
|
def visit_AnnAssign(self, node: ast.AnnAssign, bb: BB, jumps: Jumps) -> BB | None:
|
|
177
|
-
|
|
199
|
+
bb = self._build_node_value(node, bb)
|
|
200
|
+
bb = self._build_node_targets(node, bb)
|
|
201
|
+
bb.statements.append(node)
|
|
202
|
+
return bb
|
|
178
203
|
|
|
179
204
|
def visit_Expr(self, node: ast.Expr, bb: BB, jumps: Jumps) -> BB | None:
|
|
180
205
|
# This is an expression statement where the value is discarded
|
|
@@ -262,6 +287,7 @@ class CFGBuilder(AstVisitor[BB | None]):
|
|
|
262
287
|
|
|
263
288
|
def visit_Return(self, node: ast.Return, bb: BB, jumps: Jumps) -> BB | None:
|
|
264
289
|
bb = self._build_node_value(node, bb)
|
|
290
|
+
bb.statements.append(node)
|
|
265
291
|
self.cfg.link(bb, jumps.return_bb)
|
|
266
292
|
return None
|
|
267
293
|
|
|
@@ -572,7 +598,7 @@ class BranchBuilder(AstVisitor[None]):
|
|
|
572
598
|
comparators[:-1], node.ops, comparators[1:], strict=True
|
|
573
599
|
)
|
|
574
600
|
]
|
|
575
|
-
conj = ast.BoolOp(op=ast.And(), values=values)
|
|
601
|
+
conj = ast.BoolOp(op=ast.And(), values=values) # type: ignore[arg-type]
|
|
576
602
|
set_location_from(conj, node)
|
|
577
603
|
self.visit_BoolOp(conj, bb, true_bb, false_bb)
|
|
578
604
|
else:
|
|
@@ -668,6 +694,9 @@ def is_comptime_expression(node: ast.AST) -> ComptimeExpr | None:
|
|
|
668
694
|
|
|
669
695
|
Otherwise, returns `None`.
|
|
670
696
|
"""
|
|
697
|
+
if isinstance(node, ComptimeExpr):
|
|
698
|
+
return node
|
|
699
|
+
|
|
671
700
|
if (
|
|
672
701
|
isinstance(node, ast.Call)
|
|
673
702
|
and isinstance(node.func, ast.Name)
|
|
@@ -679,8 +708,8 @@ def is_comptime_expression(node: ast.AST) -> ComptimeExpr | None:
|
|
|
679
708
|
case [arg]:
|
|
680
709
|
pass
|
|
681
710
|
case args:
|
|
682
|
-
arg = with_loc(node, ast.Tuple(elts=args, ctx=ast.Load))
|
|
683
|
-
return with_loc(node, ComptimeExpr(
|
|
711
|
+
arg = with_loc(node, ast.Tuple(elts=args, ctx=ast.Load)) # type: ignore[arg-type]
|
|
712
|
+
return with_loc(node, ComptimeExpr(arg))
|
|
684
713
|
return None
|
|
685
714
|
|
|
686
715
|
|
|
@@ -701,7 +730,7 @@ def is_illegal_in_list_comp(node: ast.AST) -> bool:
|
|
|
701
730
|
|
|
702
731
|
def make_var(name: str, loc: ast.AST | None = None) -> ast.Name:
|
|
703
732
|
"""Creates an `ast.Name` node."""
|
|
704
|
-
node = ast.Name(id=name, ctx=ast.Load)
|
|
733
|
+
node = ast.Name(id=name, ctx=ast.Load) # type: ignore[arg-type]
|
|
705
734
|
if loc is not None:
|
|
706
735
|
set_location_from(node, loc)
|
|
707
736
|
return node
|
|
@@ -715,5 +744,8 @@ def make_assign(lhs: list[ast.AST], value: ast.expr) -> ast.Assign:
|
|
|
715
744
|
if len(lhs) == 1:
|
|
716
745
|
target = lhs[0]
|
|
717
746
|
else:
|
|
718
|
-
target = with_loc(
|
|
719
|
-
|
|
747
|
+
target = with_loc(
|
|
748
|
+
value,
|
|
749
|
+
ast.Tuple(elts=lhs, ctx=ast.Store()), # type: ignore[arg-type]
|
|
750
|
+
)
|
|
751
|
+
return with_loc(value, ast.Assign(targets=[target], value=value)) # type: ignore[list-item]
|
{guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/cfg/cfg.py
RENAMED
|
@@ -118,7 +118,7 @@ class CFG(BaseCFG[BB]):
|
|
|
118
118
|
# initial value in the liveness analysis. This solves the edge case that
|
|
119
119
|
# borrowed variables should be considered live, even if the exit is actually
|
|
120
120
|
# unreachable (to avoid linearity violations later).
|
|
121
|
-
inout_live =
|
|
121
|
+
inout_live = dict.fromkeys(inout_vars, self.exit_bb)
|
|
122
122
|
self.live_before = LivenessAnalysis(
|
|
123
123
|
stats, initial=inout_live, include_unreachable=True
|
|
124
124
|
).run(self.bbs)
|
{guppylang_internals-0.26.0 → guppylang_internals-0.28.0}/src/guppylang_internals/checker/core.py
RENAMED
|
@@ -384,7 +384,7 @@ class Globals:
|
|
|
384
384
|
case _:
|
|
385
385
|
return assert_never(ty)
|
|
386
386
|
|
|
387
|
-
type_defn = cast(TypeDef, ENGINE.get_checked(type_defn.id))
|
|
387
|
+
type_defn = cast("TypeDef", ENGINE.get_checked(type_defn.id))
|
|
388
388
|
if type_defn.id in DEF_STORE.impls and name in DEF_STORE.impls[type_defn.id]:
|
|
389
389
|
def_id = DEF_STORE.impls[type_defn.id][name]
|
|
390
390
|
defn = ENGINE.get_parsed(def_id)
|
|
@@ -44,18 +44,6 @@ class ComptimeExprIncoherentListError(Error):
|
|
|
44
44
|
span_label: ClassVar[str] = "List contains elements with different types"
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
@dataclass(frozen=True)
|
|
48
|
-
class TketNotInstalled(Error):
|
|
49
|
-
title: ClassVar[str] = "Tket not installed"
|
|
50
|
-
span_label: ClassVar[str] = (
|
|
51
|
-
"Experimental pytket compatibility requires `tket` to be installed"
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
@dataclass(frozen=True)
|
|
55
|
-
class InstallInstruction(Help):
|
|
56
|
-
message: ClassVar[str] = "Install tket: `pip install tket`"
|
|
57
|
-
|
|
58
|
-
|
|
59
47
|
@dataclass(frozen=True)
|
|
60
48
|
class PytketSignatureMismatch(Error):
|
|
61
49
|
title: ClassVar[str] = "Signature mismatch"
|
|
@@ -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
|
|