cpython icon indicating copy to clipboard operation
cpython copied to clipboard

Source location of match sub-expressions are incorrect

Open iritkatriel opened this issue 3 years ago • 1 comments

def f(x):
  match x:
    case a,b:
        return 1

import dis
from pprint import pprint as pp
def pos(p):
    return (p.lineno, p.end_lineno, p.col_offset, p.end_col_offset)

pp([(pos(x.positions), x.opname, x.argval) for x in dis.get_instructions(f)])

Output is:

[((2, 2, 0, 0), 'RESUME', 0),
 ((3, 3, 8, 9), 'LOAD_FAST', 'x'),
 ((4, 4, 9, 12), 'MATCH_SEQUENCE', None),
 ((4, 4, 9, 12), 'POP_JUMP_IF_FALSE', 32),
 ((4, 4, 9, 12), 'GET_LEN', None),
 ((4, 4, 9, 12), 'LOAD_CONST', 2),
 ((4, 4, 9, 12), 'COMPARE_OP', '=='),
 ((4, 4, 9, 12), 'POP_JUMP_IF_FALSE', 32),
 ((4, 4, 9, 12), 'UNPACK_SEQUENCE', 2),
 ((4, 4, 11, 12), 'STORE_FAST', 'a'),           <-- incorrect
 ((4, 4, 11, 12), 'STORE_FAST', 'b'),
 ((5, 5, 15, 16), 'LOAD_CONST', 1),
 ((5, 5, 15, 16), 'RETURN_VALUE', None),
 ((4, 4, 9, 12), 'POP_TOP', None),
 ((4, 4, 9, 12), 'LOAD_CONST', None),
 ((4, 4, 9, 12), 'RETURN_VALUE', None)]
  • PR: gh-98775

iritkatriel avatar Oct 27 '22 10:10 iritkatriel

FYI @nedbat .

iritkatriel avatar Oct 27 '22 11:10 iritkatriel

The issue with name stores is pretty tricky, and stems from the fact that names are only bound once the entire pattern has matched. Fixing the locations for name stores in "normal" patterns won't be too hard (just keep the original node nearby and use that location for the final store).

However, or-patterns pose a challenge. For example, what should the location be when storing a and b?

match ...:
    case [True, a, b] | [False, b, a]:
       ...

There's only one store instruction for each (at the very end), so I still think "the whole pattern" makes sense.

brandtbucher avatar Nov 18 '22 20:11 brandtbucher