Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions mypyc/irbuild/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from collections.abc import Sequence
from typing import Callable

from mypy.checkexpr import try_getting_literal
from mypy.nodes import (
ARG_NAMED,
ARG_POS,
Expand Down Expand Up @@ -50,7 +51,7 @@
UnaryExpr,
Var,
)
from mypy.types import Instance, ProperType, TupleType, TypeType, get_proper_type
from mypy.types import Instance, LiteralType, ProperType, TupleType, TypeType, get_proper_type
from mypyc.common import MAX_SHORT_INT
from mypyc.ir.class_ir import ClassIR
from mypyc.ir.func_ir import FUNC_CLASSMETHOD, FUNC_STATICMETHOD
Expand Down Expand Up @@ -784,9 +785,26 @@ def try_specialize_in_expr(
items = [builder.accept(item) for item in rhs.items]
elif isinstance(builder.node_type(rhs), RTuple):
left = builder.accept(lhs)
tuple_val = builder.accept(rhs)
assert isinstance(tuple_val.type, RTuple)
items = [builder.add(TupleGet(tuple_val, i)) for i in range(len(tuple_val.type.types))]
proper_type = get_proper_type(builder.types[rhs])
assert isinstance(proper_type, TupleType)
literal_items = list(map(try_getting_literal, proper_type.items))
if None not in literal_items:
# If all tuple items are literals we don't even need to accept the tuple
# TODO: should we use object_rprimitive? prob not, what do?
items = [LoadLiteral(literal.value, object_rprimitive) for literal in literal_items]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if all items are literals we can probably have a fast-false path via type check, and if the type check passes the subsequent equality checks will be much faster

else:
tuple_val = builder.accept(rhs)
assert isinstance(tuple_val.type, RTuple)
proper_type = get_proper_type(builder.types[rhs])
items = [
# TODO: should we use object_rprimitive? prob not, what do?
(
LoadLiteral(typ.value, object_rprimitive)
if isinstance(typ, LiteralType)
else builder.add(TupleGet(tuple_val, i))
)
for i, typ in enumerate(map(try_getting_literal, proper_type.items))
]

if items is not None:
assert left is not None
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would be worth weaving the item-getting process into the equality checks so in some cases we can exit early without fully loading the tuple items

Expand Down
Loading