Skip to content

Commit b957495

Browse files
[mypyc] feat: support negative index in TupleGet op
This PR modifies `TupleGet.__init__` to automatically convert negative indexes to positive indexes instead of crashing at the assert This won't change functionality on its own, but will allow us to pass negative values in python#19972 so I think we should consider this PR a prerequisite to that one
1 parent a0665e1 commit b957495

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

mypyc/ir/ops.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,10 +1045,15 @@ class TupleGet(RegisterOp):
10451045

10461046
def __init__(self, src: Value, index: int, line: int = -1, *, borrow: bool = False) -> None:
10471047
super().__init__(line)
1048+
assert isinstance(
1049+
src.type, RTuple
1050+
), "TupleGet only operates on tuples, not {type(src.type).__name__}"
1051+
src_len = len(src.type.types)
10481052
self.src = src
10491053
self.index = index
1050-
assert isinstance(src.type, RTuple), "TupleGet only operates on tuples"
1051-
assert index >= 0
1054+
if index < 0:
1055+
self.index += src_len
1056+
assert self.index <= src_len - 1, f"Index out of range.\nsource type: {src.type}\nindex: {index}"
10521057
self.type = src.type.types[index]
10531058
self.is_borrowed = borrow
10541059

@@ -1073,11 +1078,19 @@ class Cast(RegisterOp):
10731078

10741079
error_kind = ERR_MAGIC
10751080

1076-
def __init__(self, src: Value, typ: RType, line: int, *, borrow: bool = False) -> None:
1081+
def __init__(
1082+
self, src: Value, typ: RType, line: int, *, borrow: bool = False, unchecked: bool = False
1083+
) -> None:
10771084
super().__init__(line)
10781085
self.src = src
10791086
self.type = typ
1087+
# If true, don't incref the result.
10801088
self.is_borrowed = borrow
1089+
# If true, don't perform a runtime type check (only changes the static type of
1090+
# the operand). Used when we know that the cast will always succeed.
1091+
self.is_unchecked = unchecked
1092+
if unchecked:
1093+
self.error_kind = ERR_NEVER
10811094

10821095
def sources(self) -> list[Value]:
10831096
return [self.src]
@@ -1213,6 +1226,7 @@ def __init__(
12131226
var_arg_idx: int = -1,
12141227
*,
12151228
is_pure: bool = False,
1229+
returns_null: bool = False,
12161230
) -> None:
12171231
self.error_kind = error_kind
12181232
super().__init__(line)
@@ -1227,7 +1241,10 @@ def __init__(
12271241
# and all the arguments are immutable. Pure functions support
12281242
# additional optimizations. Pure functions never fail.
12291243
self.is_pure = is_pure
1230-
if is_pure:
1244+
# The function might return a null value that does not indicate
1245+
# an error.
1246+
self.returns_null = returns_null
1247+
if is_pure or returns_null:
12311248
assert error_kind == ERR_NEVER
12321249

12331250
def sources(self) -> list[Value]:

0 commit comments

Comments
 (0)