Skip to content

Assertion failure when part of expression is unreachable #761

@JukkaL

Description

@JukkaL

This code results in an assertion failure within mypyc:

import sys

y = sys.platform == "x" and sys.version_info < (3, 6)

Here's the traceback:

Traceback (most recent call last):
  File "build/setup.py", line 5, in <module>
    ext_modules=mypycify(['t.py'], opt_level="3"),
  File "/home/jukka/src/mypy/mypyc/build.py", line 492, in mypycify
    skip_cgen_input=skip_cgen_input,
  File "/home/jukka/src/mypy/mypyc/build.py", line 401, in mypyc_build
    compiler_options=compiler_options)
  File "/home/jukka/src/mypy/mypyc/build.py", line 201, in generate_c
    result, compiler_options=compiler_options, errors=errors, groups=groups)
  File "/home/jukka/src/mypy/mypyc/codegen/emitmodule.py", line 408, in compile_modules_to_c
    modules = compile_modules_to_ir(result, mapper, compiler_options, errors)
  File "/home/jukka/src/mypy/mypyc/codegen/emitmodule.py", line 255, in compile_modules_to_ir
    scc_ir = compile_scc_to_ir(trees, result, mapper, compiler_options, errors)
  File "/home/jukka/src/mypy/mypyc/codegen/emitmodule.py", line 207, in compile_scc_to_ir
    scc, result.graph, result.types, mapper, compiler_options, errors
  File "/usr/local/lib/python3.6/contextlib.py", line 52, in inner
    return func(*args, **kwds)
  File "/home/jukka/src/mypy/mypyc/irbuild/main.py", line 80, in build_ir
    transform_mypy_file(builder, module)
  File "/home/jukka/src/mypy/mypyc/irbuild/main.py", line 123, in transform_mypy_file
    builder.accept(node)
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 160, in accept
    node.accept(self.visitor)
  File "/home/jukka/src/mypy/mypy/nodes.py", line 1063, in accept
    return visitor.visit_assignment_stmt(self)
  File "/home/jukka/src/mypy/mypyc/irbuild/visitor.py", line 135, in visit_assignment_stmt
    transform_assignment_stmt(self.builder, stmt)
  File "/home/jukka/src/mypy/mypyc/irbuild/statement.py", line 83, in transform_assignment_stmt
    rvalue_reg = builder.accept(stmt.rvalue)
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 149, in accept
    res = node.accept(self.visitor)
  File "/home/jukka/src/mypy/mypy/nodes.py", line 1737, in accept
    return visitor.visit_op_expr(self)
  File "/home/jukka/src/mypy/mypyc/irbuild/visitor.py", line 199, in visit_op_expr
    return transform_op_expr(self.builder, expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/expression.py", line 322, in transform_op_expr
    return builder.shortcircuit_expr(expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 795, in shortcircuit_expr
    expr.line
  File "/home/jukka/src/mypy/mypyc/irbuild/ll_builder.py", line 821, in shortcircuit_helper
    right_value = right()
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 794, in <lambda>
    lambda: self.accept(expr.right),
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 149, in accept
    res = node.accept(self.visitor)
  File "/home/jukka/src/mypy/mypy/nodes.py", line 1762, in accept
    return visitor.visit_comparison_expr(self)
  File "/home/jukka/src/mypy/mypyc/irbuild/visitor.py", line 208, in visit_comparison_expr
    return transform_comparison_expr(self.builder, expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/expression.py", line 479, in transform_comparison_expr
    return go(0, builder.accept(e.operands[0]))
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 149, in accept
    res = node.accept(self.visitor)
  File "/home/jukka/src/mypy/mypy/nodes.py", line 1497, in accept
    return visitor.visit_member_expr(self)
  File "/home/jukka/src/mypy/mypyc/irbuild/visitor.py", line 187, in visit_member_expr
    return transform_member_expr(self.builder, expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/expression.py", line 106, in transform_member_expr
    obj = builder.accept(expr.expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/builder.py", line 149, in accept
    res = node.accept(self.visitor)
  File "/home/jukka/src/mypy/mypy/nodes.py", line 1477, in accept
    return visitor.visit_name_expr(self)
  File "/home/jukka/src/mypy/mypyc/irbuild/visitor.py", line 184, in visit_name_expr
    return transform_name_expr(self.builder, expr)
  File "/home/jukka/src/mypy/mypyc/irbuild/expression.py", line 44, in transform_name_expr
    assert expr.node, "RefExpr not resolved"
t.py:3: AssertionError: RefExpr not resolved

I haven't looked into this in detail yet, but I believe that the problem is that sys.version_info < (3, 6) is not semantically analyzed, since it's considered unreachable, but we assume that everything has been semantically analyzed. Instead, we could generate code that raises an exception if we reach code that is supposed to be unreachable.

As a workaround, we can rewrite the platform check in a way that isn't recognized by mypy, such as by using the in operator:

import sys

y = sys.platform in ["x"] and sys.version_info < (3, 6)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions