Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8aa385e

Browse files
authored
[mypyc] Fix compilation of unreachable expressions (#10228)
Unreachable generator expressions are still failing, but most others work. Fixes mypyc/mypyc#761.
1 parent d3ba896 commit 8aa385e

4 files changed

Lines changed: 131 additions & 2 deletions

File tree

mypyc/irbuild/expression.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
from mypy.types import TupleType, get_proper_type, Instance
1818

1919
from mypyc.common import MAX_SHORT_INT
20-
from mypyc.ir.ops import Value, Register, TupleGet, TupleSet, BasicBlock, Assign, LoadAddress
20+
from mypyc.ir.ops import (
21+
Value, Register, TupleGet, TupleSet, BasicBlock, Assign, LoadAddress, RaiseStandardError
22+
)
2123
from mypyc.ir.rtypes import (
2224
RTuple, object_rprimitive, is_none_rprimitive, int_rprimitive, is_int_rprimitive
2325
)
@@ -40,7 +42,11 @@
4042

4143

4244
def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value:
43-
assert expr.node, "RefExpr not resolved"
45+
if expr.node is None:
46+
builder.add(RaiseStandardError(RaiseStandardError.RUNTIME_ERROR,
47+
"mypyc internal error: should be unreachable",
48+
expr.line))
49+
return builder.none()
4450
fullname = expr.node.fullname
4551
if fullname in builtin_names:
4652
typ, src = builtin_names[fullname]
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Test cases for unreachable expressions
2+
3+
[case testUnreachableMemberExpr]
4+
import sys
5+
6+
def f() -> None:
7+
y = sys.platform == "x" and sys.version_info > (3, 5)
8+
[out]
9+
def f():
10+
r0 :: object
11+
r1 :: str
12+
r2 :: object
13+
r3, r4 :: str
14+
r5 :: int32
15+
r6 :: bit
16+
r7 :: object
17+
r8, r9, r10 :: bit
18+
r11, r12 :: bool
19+
r13 :: object
20+
r14 :: str
21+
r15 :: object
22+
r16 :: tuple[int, int]
23+
r17, r18 :: object
24+
r19, y :: bool
25+
L0:
26+
r0 = sys :: module
27+
r1 = 'platform'
28+
r2 = CPyObject_GetAttr(r0, r1)
29+
r3 = cast(str, r2)
30+
r4 = 'x'
31+
r5 = PyUnicode_Compare(r3, r4)
32+
r6 = r5 == -1
33+
if r6 goto L1 else goto L3 :: bool
34+
L1:
35+
r7 = PyErr_Occurred()
36+
r8 = r7 != 0
37+
if r8 goto L2 else goto L3 :: bool
38+
L2:
39+
r9 = CPy_KeepPropagating()
40+
L3:
41+
r10 = r5 == 0
42+
if r10 goto L5 else goto L4 :: bool
43+
L4:
44+
r11 = r10
45+
goto L6
46+
L5:
47+
r12 = raise RuntimeError('mypyc internal error: should be unreachable')
48+
r13 = box(None, 1)
49+
r14 = 'version_info'
50+
r15 = CPyObject_GetAttr(r13, r14)
51+
r16 = (6, 10)
52+
r17 = box(tuple[int, int], r16)
53+
r18 = PyObject_RichCompare(r15, r17, 4)
54+
r19 = unbox(bool, r18)
55+
r11 = r19
56+
L6:
57+
y = r11
58+
return 1
59+
60+
[case testUnreachableNameExpr]
61+
import sys
62+
63+
def f() -> None:
64+
y = sys.platform == 'x' and foobar
65+
[out]
66+
def f():
67+
r0 :: object
68+
r1 :: str
69+
r2 :: object
70+
r3, r4 :: str
71+
r5 :: int32
72+
r6 :: bit
73+
r7 :: object
74+
r8, r9, r10 :: bit
75+
r11, r12 :: bool
76+
r13 :: object
77+
r14, y :: bool
78+
L0:
79+
r0 = sys :: module
80+
r1 = 'platform'
81+
r2 = CPyObject_GetAttr(r0, r1)
82+
r3 = cast(str, r2)
83+
r4 = 'x'
84+
r5 = PyUnicode_Compare(r3, r4)
85+
r6 = r5 == -1
86+
if r6 goto L1 else goto L3 :: bool
87+
L1:
88+
r7 = PyErr_Occurred()
89+
r8 = r7 != 0
90+
if r8 goto L2 else goto L3 :: bool
91+
L2:
92+
r9 = CPy_KeepPropagating()
93+
L3:
94+
r10 = r5 == 0
95+
if r10 goto L5 else goto L4 :: bool
96+
L4:
97+
r11 = r10
98+
goto L6
99+
L5:
100+
r12 = raise RuntimeError('mypyc internal error: should be unreachable')
101+
r13 = box(None, 1)
102+
r14 = unbox(bool, r13)
103+
r11 = r14
104+
L6:
105+
y = r11
106+
return 1

mypyc/test-data/run-misc.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,3 +1057,19 @@ def test_complex() -> None:
10571057
assert 2.5e1000j == eval('2.5e1000j')
10581058
assert 2.5e1000j + 3.5e2000 == eval('3.5e2000 + 2.5e1000j')
10591059
assert -2.5e1000j == eval('-2.5e1000j')
1060+
1061+
[case testUnreachableExpressions]
1062+
from typing import cast
1063+
import sys
1064+
1065+
A = sys.platform == 'x' and foobar
1066+
B = sys.platform == 'x' and sys.foobar
1067+
C = sys.platform == 'x' and f(a, -b, 'y') > [c + e, g(y=2)]
1068+
C = sys.platform == 'x' and cast(a, b[c])
1069+
C = sys.platform == 'x' and (lambda x: y + x)
1070+
# TODO: This still doesn't work
1071+
# C = sys.platform == 'x' and (x for y in z)
1072+
1073+
assert not A
1074+
assert not B
1075+
assert not C

mypyc/test/test_irbuild.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
'irbuild-strip-asserts.test',
3232
'irbuild-int.test',
3333
'irbuild-vectorcall.test',
34+
'irbuild-unreachable.test',
3435
]
3536

3637

0 commit comments

Comments
 (0)