diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 59ecc4ac2c5c..d881bd017fc9 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -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, @@ -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 @@ -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] + 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