Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/diagnostics' into diag/rest
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-koch committed Nov 11, 2024
2 parents 575d373 + c4a2aca commit 2b69b80
Show file tree
Hide file tree
Showing 132 changed files with 2,184 additions and 1,065 deletions.
62 changes: 38 additions & 24 deletions examples/demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,14 @@
"name": "stderr",
"output_type": "stream",
"text": [
"Guppy compilation failed. Error in file <In [6]>:6\n",
"Error: Operator not defined (at <In [6]>:6:11)\n",
" | \n",
"4 | def bad(x: int) -> int:\n",
"5 | # Try to add a tuple to an int\n",
"6 | return x + (x, x)\n",
" | ^^^^^^^^^^ Binary operator `+` not defined for `int` and `(int, int)`\n",
"\n",
"4: def bad(x: int) -> int:\n",
"5: # Try to add a tuple to an int\n",
"6: return x + (x, x)\n",
" ^^^^^^^^^^\n",
"GuppyTypeError: Binary operator `+` not defined for arguments of type `int` and `(int, int)`\n"
"Guppy compilation failed due to 1 previous error\n"
]
}
],
Expand Down Expand Up @@ -306,13 +307,18 @@
"name": "stderr",
"output_type": "stream",
"text": [
"Guppy compilation failed. Error in file <In [9]>:6\n",
"Error: Linearity violation (at <In [9]>:6:10)\n",
" | \n",
"4 | @guppy(bad_module)\n",
"5 | def bad(q: qubit @owned) -> qubit:\n",
"6 | cx(q, q)\n",
" | ^ Variable `q` with linear type `qubit` cannot be borrowed\n",
" | ...\n",
" | \n",
"6 | cx(q, q)\n",
" | - since it was already borrowed here\n",
"\n",
"4: @guppy(bad_module)\n",
"5: def bad(q: qubit @owned) -> qubit:\n",
"6: cx(q, q)\n",
" ^\n",
"GuppyError: Variable `q` with linear type `qubit` was already used (at 6:7)\n"
"Guppy compilation failed due to 1 previous error\n"
]
}
],
Expand Down Expand Up @@ -350,13 +356,16 @@
"name": "stderr",
"output_type": "stream",
"text": [
"Guppy compilation failed. Error in file <In [10]>:7\n",
"Error: Linearity violation (at <In [10]>:7:7)\n",
" | \n",
"5 | def bad(q: qubit @owned) -> qubit:\n",
"6 | tmp = qubit()\n",
"7 | cx(tmp, q)\n",
" | ^^^ Variable `tmp` with linear type `qubit` is leaked\n",
"\n",
"5: def bad(q: qubit @owned) -> qubit:\n",
"6: tmp = qubit()\n",
"7: cx(tmp, q)\n",
" ^^^\n",
"GuppyError: Variable `tmp` with linear type `qubit` is not used on all control-flow paths\n"
"Help: Make sure that `tmp` is consumed or returned to avoid the leak\n",
"\n",
"Guppy compilation failed due to 1 previous error\n"
]
}
],
Expand Down Expand Up @@ -497,13 +506,18 @@
"name": "stderr",
"output_type": "stream",
"text": [
"Guppy compilation failed. Error in file <In [14]>:6\n",
"Error: Illegal assignment (at <In [14]>:6:8)\n",
" | \n",
"4 | def outer(x: int) -> int:\n",
"5 | def nested() -> None:\n",
"6 | x += 1 # Mutation of captured variable x is not allowed\n",
" | ^^^^^^ Variable `x` may not be assigned to since `x` is captured\n",
" | from an outer scope\n",
" | \n",
"4 | def outer(x: int) -> int:\n",
" | ------ `x` defined here\n",
"\n",
"4: def outer(x: int) -> int:\n",
"5: def nested() -> None:\n",
"6: x += 1 # Mutation of captured variable x is not allowed\n",
" ^^^^^^\n",
"GuppyError: Variable `x` defined in an outer scope (at 4:10) may not be assigned to\n"
"Guppy compilation failed due to 1 previous error\n"
]
}
],
Expand Down
4 changes: 2 additions & 2 deletions guppylang/checker/cfg_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __init__(self, input_tys: list[Type], output_ty: Type) -> None:


def check_cfg(
cfg: CFG, inputs: Row[Variable], return_ty: Type, globals: Globals
cfg: CFG, inputs: Row[Variable], return_ty: Type, func_name: str, globals: Globals
) -> CheckedCFG[Place]:
"""Type checks a control-flow graph.
Expand Down Expand Up @@ -126,7 +126,7 @@ def check_cfg(
# Finally, run the linearity check
from guppylang.checker.linearity_checker import check_cfg_linearity

linearity_checked_cfg = check_cfg_linearity(checked_cfg, globals)
linearity_checked_cfg = check_cfg_linearity(checked_cfg, func_name, globals)

return linearity_checked_cfg

Expand Down
29 changes: 29 additions & 0 deletions guppylang/checker/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import (
TYPE_CHECKING,
Any,
ClassVar,
Generic,
NamedTuple,
TypeAlias,
Expand All @@ -20,6 +21,7 @@
from guppylang.definition.common import DefId, Definition
from guppylang.definition.ty import TypeDef
from guppylang.definition.value import CallableDef
from guppylang.diagnostic import Error
from guppylang.tys.builtin import (
array_type_def,
bool_type_def,
Expand Down Expand Up @@ -49,6 +51,18 @@
from guppylang.definition.struct import StructField


@dataclass(frozen=True)
class UnsupportedError(Error):
title: ClassVar[str] = "Unsupported"
things: str
singular: bool = False

@property
def rendered_span_label(self) -> str:
is_are = "is" if self.singular else "are"
return f"{self.things} {is_are} not supported"


#: A "place" is a description for a storage location of a local value that users
#: can refer to in their program.
#:
Expand Down Expand Up @@ -85,6 +99,11 @@ def id(self) -> "Variable.Id":
"""The unique `PlaceId` identifier for this place."""
return Variable.Id(self.name)

@cached_property
def root(self) -> "Variable":
"""The root variable of this place."""
return self

@property
def describe(self) -> str:
"""A human-readable description of this place for error messages."""
Expand Down Expand Up @@ -123,6 +142,11 @@ def id(self) -> "FieldAccess.Id":
"""The unique `PlaceId` identifier for this place."""
return FieldAccess.Id(self.parent.id, self.field.name)

@cached_property
def root(self) -> "Variable":
"""The root variable of this place."""
return self.parent.root

@property
def ty(self) -> Type:
"""The type of this place."""
Expand Down Expand Up @@ -182,6 +206,11 @@ def defined_at(self) -> AstNode | None:
"""Optional location where this place was last assigned to."""
return self.parent.defined_at

@cached_property
def root(self) -> "Variable":
"""The root variable of this place."""
return self.parent.root

@property
def describe(self) -> str:
"""A human-readable description of this place for error messages."""
Expand Down
Loading

0 comments on commit 2b69b80

Please sign in to comment.