Skip to content

Commit fc410cb

Browse files
authored
[mypyc] Fix semantics for walrus expression in tuple (#21249)
Fixes mypyc/mypyc#1179
1 parent c6795cc commit fc410cb

7 files changed

Lines changed: 98 additions & 63 deletions

File tree

mypyc/irbuild/expression.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,12 @@ def transform_tuple_expr(builder: IRBuilder, expr: TupleExpr) -> Value:
11131113
items = []
11141114
for item_expr, item_type in zip(expr.items, types):
11151115
reg = builder.accept(item_expr)
1116-
items.append(builder.coerce(reg, item_type, item_expr.line))
1116+
item = builder.coerce(reg, item_type, item_expr.line)
1117+
if isinstance(item, Register):
1118+
temp = Register(item.type)
1119+
builder.assign(temp, item, item_expr.line)
1120+
item = temp
1121+
items.append(item)
11171122
return builder.add(TupleSet(items, expr.line))
11181123

11191124

mypyc/test-data/irbuild-basic.test

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,11 +1665,14 @@ def h() -> Tuple[int, int, int]:
16651665
return f(1, *(2, 3))
16661666
[out]
16671667
def f(a, b, c):
1668-
a, b, c :: int
1669-
r0 :: tuple[int, int, int]
1668+
a, b, c, r0, r1, r2 :: int
1669+
r3 :: tuple[int, int, int]
16701670
L0:
1671-
r0 = (a, b, c)
1672-
return r0
1671+
r0 = a
1672+
r1 = b
1673+
r2 = c
1674+
r3 = (r0, r1, r2)
1675+
return r3
16731676
def g():
16741677
r0 :: tuple[int, int, int]
16751678
r1 :: dict
@@ -1724,11 +1727,14 @@ def h() -> Tuple[int, int, int]:
17241727
return f(1, **{'b': 2, 'c': 3})
17251728
[out]
17261729
def f(a, b, c):
1727-
a, b, c :: int
1728-
r0 :: tuple[int, int, int]
1730+
a, b, c, r0, r1, r2 :: int
1731+
r3 :: tuple[int, int, int]
17291732
L0:
1730-
r0 = (a, b, c)
1731-
return r0
1733+
r0 = a
1734+
r1 = b
1735+
r2 = c
1736+
r3 = (r0, r1, r2)
1737+
return r3
17321738
def g():
17331739
r0, r1, r2 :: str
17341740
r3, r4, r5 :: object

mypyc/test-data/irbuild-float.test

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,16 @@ def f(x: int) -> None:
483483
t: tuple[float, float, float] = (x, 2.5, -7)
484484
[out]
485485
def f(x):
486-
x :: int
487-
r0 :: tuple[int, float, int]
488-
r1 :: int
489-
r2 :: float
490-
r3, t :: tuple[float, float, float]
486+
x, r0 :: int
487+
r1 :: tuple[int, float, int]
488+
r2 :: int
489+
r3 :: float
490+
r4, t :: tuple[float, float, float]
491491
L0:
492-
r0 = (x, 2.5, -14)
493-
r1 = r0[0]
494-
r2 = CPyFloat_FromTagged(r1)
495-
r3 = (r2, 2.5, -7.0)
496-
t = r3
492+
r0 = x
493+
r1 = (r0, 2.5, -14)
494+
r2 = r1[0]
495+
r3 = CPyFloat_FromTagged(r2)
496+
r4 = (r3, 2.5, -7.0)
497+
t = r4
497498
return 1

mypyc/test-data/irbuild-i64.test

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,13 @@ def h() -> i64:
658658
return x + y + t[0]
659659
[out]
660660
def f(x, y):
661-
x, y :: i64
662-
r0 :: tuple[i64, i64]
661+
x, y, r0, r1 :: i64
662+
r2 :: tuple[i64, i64]
663663
L0:
664-
r0 = (x, y)
665-
return r0
664+
r0 = x
665+
r1 = y
666+
r2 = (r0, r1)
667+
return r2
666668
def g():
667669
r0 :: tuple[int, int]
668670
r1 :: tuple[i64, i64]
@@ -2114,33 +2116,34 @@ L3:
21142116
tt = r10
21152117
return 1
21162118
def g(n):
2117-
n :: int
2118-
r0 :: tuple[int, int]
2119-
r1 :: int
2120-
r2 :: native_int
2121-
r3 :: bit
2122-
r4, r5 :: i64
2123-
r6 :: ptr
2124-
r7 :: c_ptr
2125-
r8 :: i64
2126-
r9, t :: tuple[i64, i64]
2119+
n, r0 :: int
2120+
r1 :: tuple[int, int]
2121+
r2 :: int
2122+
r3 :: native_int
2123+
r4 :: bit
2124+
r5, r6 :: i64
2125+
r7 :: ptr
2126+
r8 :: c_ptr
2127+
r9 :: i64
2128+
r10, t :: tuple[i64, i64]
21272129
L0:
2128-
r0 = (2, n)
2129-
r1 = r0[1]
2130-
r2 = r1 & 1
2131-
r3 = r2 == 0
2132-
if r3 goto L1 else goto L2 :: bool
2130+
r0 = n
2131+
r1 = (2, r0)
2132+
r2 = r1[1]
2133+
r3 = r2 & 1
2134+
r4 = r3 == 0
2135+
if r4 goto L1 else goto L2 :: bool
21332136
L1:
2134-
r4 = r1 >> 1
2135-
r5 = r4
2137+
r5 = r2 >> 1
2138+
r6 = r5
21362139
goto L3
21372140
L2:
2138-
r6 = r1 ^ 1
2139-
r7 = r6
2140-
r8 = CPyLong_AsInt64(r7)
2141-
r5 = r8
2142-
keep_alive r1
2141+
r7 = r2 ^ 1
2142+
r8 = r7
2143+
r9 = CPyLong_AsInt64(r8)
2144+
r6 = r9
2145+
keep_alive r2
21432146
L3:
2144-
r9 = (1, r5)
2145-
t = r9
2147+
r10 = (1, r6)
2148+
t = r10
21462149
return 1

mypyc/test-data/irbuild-statements.test

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -381,15 +381,17 @@ def f3(x: int, y: int) -> Tuple[int, int]:
381381
return (x, y)
382382
[out]
383383
def f(x, y):
384-
x, y, r0, r1 :: int
385-
r2 :: tuple[int, int]
384+
x, y, r0, r1, r2, r3 :: int
385+
r4 :: tuple[int, int]
386386
L0:
387387
r0 = y
388388
r1 = x
389389
x = r0
390390
y = r1
391-
r2 = (x, y)
392-
return r2
391+
r2 = x
392+
r3 = y
393+
r4 = (r2, r3)
394+
return r4
393395
def f2(x, y, z):
394396
x :: int
395397
y :: str
@@ -399,27 +401,34 @@ def f2(x, y, z):
399401
r2 :: float
400402
a :: int
401403
b :: str
402-
c :: float
403-
r3 :: tuple[float, str, int]
404+
c, r3 :: float
405+
r4 :: str
406+
r5 :: int
407+
r6 :: tuple[float, str, int]
404408
L0:
405409
r0 = x
406410
r1 = y
407411
r2 = z
408412
a = r0
409413
b = r1
410414
c = r2
411-
r3 = (c, b, a)
412-
return r3
415+
r3 = c
416+
r4 = b
417+
r5 = a
418+
r6 = (r3, r4, r5)
419+
return r6
413420
def f3(x, y):
414-
x, y, r0, r1 :: int
415-
r2 :: tuple[int, int]
421+
x, y, r0, r1, r2, r3 :: int
422+
r4 :: tuple[int, int]
416423
L0:
417424
r0 = y
418425
r1 = x
419426
x = r0
420427
y = r1
421-
r2 = (x, y)
422-
return r2
428+
r2 = x
429+
r3 = y
430+
r4 = (r2, r3)
431+
return r4
423432

424433
[case testMultipleAssignmentBasicUnpacking]
425434
from typing import Tuple, Any

mypyc/test-data/refcount.test

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,15 +617,17 @@ def f() -> Tuple[C, C]:
617617
return a, b
618618
[out]
619619
def f():
620-
r0, a, r1, b :: __main__.C
621-
r2 :: tuple[__main__.C, __main__.C]
620+
r0, a, r1, b, r2, r3 :: __main__.C
621+
r4 :: tuple[__main__.C, __main__.C]
622622
L0:
623623
r0 = C()
624624
a = r0
625625
r1 = C()
626626
b = r1
627-
r2 = (a, b)
628-
return r2
627+
r2 = a
628+
r3 = b
629+
r4 = (r2, r3)
630+
return r4
629631

630632
[case testDecomposeTuple]
631633
from typing import Tuple

mypyc/test-data/run-tuples.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,15 @@ def test_multiply() -> None:
398398
assert 3 * (1,) == res
399399
assert multiply((1,), 3) == res
400400

401+
# Ref: https://github.com/mypyc/mypyc/issues/1179
402+
def test_tuple_with_walrus() -> None:
403+
i = 0
404+
assert (i, (i := i + 1), i, (i := i + 1), i, (i := i + 1), i) == (0, 1, 1, 2, 2, 3, 3)
405+
406+
def test_nested_tuple_with_walrus() -> None:
407+
i = 0
408+
assert ((i, i), (i := i + 1)) == ((0, 0), 1)
409+
401410
[case testIsInstance]
402411
from copysubclass import subc
403412
def test_built_in() -> None:

0 commit comments

Comments
 (0)