diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index d0e91125e80f..c19248622f1d 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -49,7 +49,15 @@ UnaryExpr, Var, ) -from mypy.types import Instance, ProperType, TupleType, TypeType, get_proper_type +from mypy.types import ( + AnyType, + Instance, + ProperType, + TupleType, + TypeOfAny, + 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 @@ -147,13 +155,11 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value: return math_literal if isinstance(expr.node, Var) and expr.node.is_final: + final_type = builder.types.get(expr) or expr.node.type + if final_type is None: + final_type = AnyType(TypeOfAny.special_form) value = builder.emit_load_final( - expr.node, - fullname, - expr.name, - builder.is_native_ref_expr(expr), - builder.types[expr], - expr.line, + expr.node, fullname, expr.name, builder.is_native_ref_expr(expr), final_type, expr.line ) if value is not None: return value @@ -208,8 +214,11 @@ def transform_member_expr(builder: IRBuilder, expr: MemberExpr) -> Value: final = builder.get_final_ref(expr) if final is not None: fullname, final_var, native = final + final_type = builder.types.get(expr) or final_var.type + if final_type is None: + final_type = AnyType(TypeOfAny.special_form) value = builder.emit_load_final( - final_var, fullname, final_var.name, native, builder.types[expr], expr.line + final_var, fullname, final_var.name, native, final_type, expr.line ) if value is not None: return value diff --git a/mypyc/test-data/irbuild-unreachable.test b/mypyc/test-data/irbuild-unreachable.test index 8eafede66b56..f8ef773a53b6 100644 --- a/mypyc/test-data/irbuild-unreachable.test +++ b/mypyc/test-data/irbuild-unreachable.test @@ -68,6 +68,34 @@ L3: y = r6 return 1 +[case testUnreachableFinalNameExpr] +from typing import Final + +ZERO: Final = 0 + +def f(x: int) -> int: + if x is None: + return ZERO + return ZERO +[out] +def f(x): + x :: int + r0, r1 :: object + r2 :: bit + r3 :: object + r4 :: int +L0: + r0 = load_address _Py_NoneStruct + r1 = box(int, x) + r2 = r1 == r0 + if r2 goto L1 else goto L2 :: bool +L1: + r3 = object 0 + r4 = unbox(int, r3) + return r4 +L2: + return 0 + [case testUnreachableStatementAfterReturn] def f(x: bool) -> int: if x: