diff --git a/mypyc/genops.py b/mypyc/genops.py index 2fc611c1c925..ec5226d6966e 100644 --- a/mypyc/genops.py +++ b/mypyc/genops.py @@ -519,7 +519,14 @@ def visit_call_expr(self, expr: CallExpr) -> int: if fn == 'len' and len(expr.args) == 1 and expr.arg_kinds == [ARG_POS]: target = self.alloc_target(RTType('int')) arg = self.accept(expr.args[0]) - self.add(PrimitiveOp(target, PrimitiveOp.LIST_LEN, arg)) + + expr_rttype = type_to_rttype(self.types[expr.args[0]]) + if expr_rttype.name == 'list': + self.add(PrimitiveOp(target, PrimitiveOp.LIST_LEN, arg)) + elif isinstance(expr_rttype, TupleRTType): + self.add(LoadInt(target, len(expr_rttype.types))) + else: + assert False, "unsupported use of len" else: target = self.alloc_target(RTType('int')) args = [self.accept(arg) for arg in expr.args] diff --git a/test-data/fixtures/ir.py b/test-data/fixtures/ir.py index 4c81f24a880a..2ace4dcfcee9 100644 --- a/test-data/fixtures/ir.py +++ b/test-data/fixtures/ir.py @@ -1,7 +1,7 @@ # These builtins stubs are used implicitly in AST to IR generation # test cases. -from typing import TypeVar, Generic, List, Iterator, Iterable +from typing import TypeVar, Generic, List, Iterator, Iterable, Sized T = TypeVar('T') @@ -33,14 +33,15 @@ class bool: pass class tuple: pass class function: pass -class list(Generic[T], Iterable[T]): +class list(Generic[T], Iterable[T], Sized): def __getitem__(self, i: int) -> T: pass def __setitem__(self, i: int, o: T) -> None: pass def __mul__(self, i: int) -> List[T]: pass def __rmul__(self, i: int) -> List[T]: pass def __iter__(self) -> Iterator[T]: pass + def __len__(self) -> int: pass def append(self, x: T) -> None: pass -def len(o: list) -> int: pass +def len(o: Sized) -> int: pass def print(*object) -> None: pass def range(x: int) -> Iterator[int]: pass diff --git a/test-data/genops-basic.test b/test-data/genops-basic.test index 22b0634e4d75..37752116ea4d 100644 --- a/test-data/genops-basic.test +++ b/test-data/genops-basic.test @@ -450,3 +450,15 @@ L0: t = (r0, r1) r2 = t[1] return r2 + +[case testTupleLen] +from typing import Tuple +def f(x: Tuple[bool, bool, int]) -> int: + return len(x) +[out] +def f(x): + x :: tuple + r0 :: int +L0: + r0 = 3 + return r0