diff --git a/guppylang-internals/src/guppylang_internals/definition/metadata.py b/guppylang-internals/src/guppylang_internals/definition/metadata.py index 4d0280575..1705435ac 100644 --- a/guppylang-internals/src/guppylang_internals/definition/metadata.py +++ b/guppylang-internals/src/guppylang_internals/definition/metadata.py @@ -3,7 +3,7 @@ from abc import ABC from dataclasses import dataclass, field, fields -from typing import Any, ClassVar, Generic, TypeVar +from typing import Any, ClassVar, Generic, Literal, TypeVar from hugr.hugr.node_port import ToNode @@ -26,12 +26,17 @@ class MetadataMaxQubits(GuppyMetadataValue[int]): key = "tket.hint.max_qubits" +class MetadataInline(GuppyMetadataValue[Literal["always"]]): + key = "tket.inline" + + @dataclass(frozen=True, init=True, kw_only=True) class GuppyMetadata: """DTO for metadata within the scope of the guppy compiler for attachment to HUGR nodes. See `add_metadata`.""" max_qubits: MetadataMaxQubits = field(default_factory=MetadataMaxQubits, init=False) + inline: MetadataInline = field(default_factory=MetadataInline, init=False) @classmethod def reserved_keys(cls) -> set[str]: diff --git a/guppylang/src/guppylang/decorator.py b/guppylang/src/guppylang/decorator.py index 5a64010ff..7deaa9456 100644 --- a/guppylang/src/guppylang/decorator.py +++ b/guppylang/src/guppylang/decorator.py @@ -3,7 +3,7 @@ import inspect from collections.abc import Callable, Sequence from types import FrameType -from typing import Any, NamedTuple, ParamSpec, TypedDict, TypeVar, cast, overload +from typing import Any, Literal, NamedTuple, ParamSpec, TypedDict, TypeVar, cast, overload from guppylang_internals.ast_util import annotate_location from guppylang_internals.compiler.core import ( @@ -94,6 +94,7 @@ class GuppyKwargs(TypedDict, total=False): dagger: bool power: bool max_qubits: int + inline: Literal["always"] link_name: str @@ -704,6 +705,7 @@ def _parse_kwargs(kwargs: GuppyKwargs) -> ParsedGuppyKwargs: metadata = GuppyMetadata() metadata.max_qubits.value = kwargs.pop("max_qubits", None) + metadata.inline.value = kwargs.pop("inline", None) link_name = kwargs.pop("link_name", None) diff --git a/tests/definition/test_metadata.py b/tests/definition/test_metadata.py index a3fc5e479..ad4c90503 100644 --- a/tests/definition/test_metadata.py +++ b/tests/definition/test_metadata.py @@ -88,3 +88,14 @@ def test_add_metadata_property_max_qubits(): add_metadata(mock_hugr_node, guppy_metadata) assert mock_hugr_node.metadata == {"tket.hint.max_qubits": 5} + + +def test_add_metadata_property_inline(): + mock_hugr_node = Mock() + mock_hugr_node.metadata = {} + + guppy_metadata = GuppyMetadata() + guppy_metadata.inline.value = "always" + add_metadata(mock_hugr_node, guppy_metadata) + + assert mock_hugr_node.metadata == {"tket.inline": "always"} diff --git a/tests/integration/test_metadata.py b/tests/integration/test_metadata.py new file mode 100644 index 000000000..dd15dea0f --- /dev/null +++ b/tests/integration/test_metadata.py @@ -0,0 +1,22 @@ +from hugr.ops import FuncDefn + +from guppylang_internals.definition.metadata import MetadataInline +from guppylang.decorator import guppy +from guppylang.std.builtins import result +from guppylang.std.quantum import ( + qubit, + measure, +) + + +def test_hinted_inline(validate) -> None: + @guppy(inline="always") + def main() -> None: + result("c", measure(qubit())) + + compiled = main.compile_function() + validate(compiled) + + hugr = compiled.modules[0] + [fd] = [data for _, data in hugr.nodes() if isinstance(data.op, FuncDefn)] + assert fd.metadata[MetadataInline.key] == "always"