Repository: python/mypy

Issue:
`mypy --install-types` segfaults
<!--
  If you're new to mypy and you're not sure whether what you're experiencing is a mypy bug, please see the "Question and Help" form
  instead.
-->

**Bug Report**

When running `mypy --install-types`, mypy segfaults instead of completing successfully.

**To Reproduce**

1. Install the following requirements with pip:

```text
mypy==0.900
mypy-extensions==0.4.3
pip==21.1.2
PyYAML==5.4.1
setuptools==57.0.0
toml==0.10.2
typed-ast==1.4.3
typing-extensions==3.10.0.0
```

2. Put the following code in `test.py`:

```python
import yaml
```

3. Run `mypy test.py`, which will display the following output:

```console
test.py:1: error: Library stubs not installed for "yaml" (or incompatible with Python 3.7)
test.py:1: note: Hint: "python3 -m pip install types-PyYAML"
test.py:1: note: (or run "mypy --install-types" to install all missing stub packages)
test.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
Found 1 error in 1 file (checked 1 source file)
```

4. Run `mypy --install-types`

**Actual Behavior**

mypy outputs the following:

```console
Installing missing stub packages:
Segmentation fault: 11
```

When running `python -X dev -m mypy --install-types`, I get the following, more verbose output:

```console
Installing missing stub packages:
Fatal Python error: Segmentation fault

Current thread 0x000000010e30cdc0 (most recent call first):
  File "/Users/ahedges/.pyenv/versions/mypy2/lib/python3.7/site-packages/mypy/__main__.py", line 11 in console_entry
  File "/Users/ahedges/.pyenv/versions/mypy2/lib/python3.7/site-packages/mypy/__main__.py", line 23 in <module>
  File "/Users/ahedges/.pyenv/versions/3.7.10/lib/python3.7/runpy.py", line 85 in _run_code
  File "/Users/ahedges/.pyenv/versions/3.7.10/lib/python3.7/runpy.py", line 193 in _run_module_as_main
Segmentation fault: 11
```

**Your Environment**

- Mypy version used: `0.900`
- Mypy command-line flags: None
- Mypy configuration options from `mypy.ini` (and other config files): None
- Python version used: `3.7.10`
- Operating system and version: macOS 10.15.7 (19H1030)


Discussion:

Resolving patch:
diff --git a/mypyc/irbuild/for_helpers.py b/mypyc/irbuild/for_helpers.py
--- a/mypyc/irbuild/for_helpers.py
+++ b/mypyc/irbuild/for_helpers.py
@@ -88,7 +88,10 @@ def for_loop_helper(builder: IRBuilder, index: Lvalue, expr: Expression,
     builder.activate_block(exit_block)
 
 
-def for_loop_helper_with_index(builder: IRBuilder, index: Lvalue, expr: Expression,
+def for_loop_helper_with_index(builder: IRBuilder,
+                               index: Lvalue,
+                               expr: Expression,
+                               expr_reg: Value,
                                body_insts: Callable[[Value], None], line: int) -> None:
     """Generate IR for a sequence iteration.
 
@@ -101,7 +104,6 @@ def for_loop_helper_with_index(builder: IRBuilder, index: Lvalue, expr: Expressi
         body_insts: a function that generates the body of the loop.
                     It needs a index as parameter.
     """
-    expr_reg = builder.accept(expr)
     assert is_sequence_rprimitive(expr_reg.type)
     target_type = builder.get_sequence_type(expr)
 
@@ -163,16 +165,15 @@ def sequence_from_generator_preallocate_helper(
     if len(gen.sequences) == 1 and len(gen.indices) == 1 and len(gen.condlists[0]) == 0:
         rtype = builder.node_type(gen.sequences[0])
         if is_list_rprimitive(rtype) or is_tuple_rprimitive(rtype):
-
-            length = builder.builder.builtin_len(builder.accept(gen.sequences[0]),
-                                                 gen.line, use_pyssize_t=True)
+            sequence = builder.accept(gen.sequences[0])
+            length = builder.builder.builtin_len(sequence, gen.line, use_pyssize_t=True)
             target_op = empty_op_llbuilder(length, gen.line)
 
             def set_item(item_index: Value) -> None:
                 e = builder.accept(gen.left_expr)
                 builder.call_c(set_item_op, [target_op, item_index, e], gen.line)
 
-            for_loop_helper_with_index(builder, gen.indices[0], gen.sequences[0],
+            for_loop_helper_with_index(builder, gen.indices[0], gen.sequences[0], sequence,
                                        set_item, gen.line)
 
             return target_op


Test patch:
diff --git a/mypyc/test-data/run-misc.test b/mypyc/test-data/run-misc.test
--- a/mypyc/test-data/run-misc.test
+++ b/mypyc/test-data/run-misc.test
@@ -485,6 +485,8 @@ print(native.x)
 77
 
 [case testComprehensions]
+from typing import List
+
 # A list comprehension
 l = [str(x) + "     " + str(y) + "   " + str(x*y) for x in range(10)
      if x != 6 if x != 5 for y in range(x) if y*x != 8]
@@ -498,6 +500,17 @@ def pred(x: int) -> bool:
 # eventually and will raise an exception.
 l2 = [x for x in range(10) if x <= 6 if pred(x)]
 
+src = ['x']
+
+def f() -> List[str]:
+    global src
+    res = src
+    src = []
+    return res
+
+l3 = [s for s in f()]
+l4 = [s for s in f()]
+
 # A dictionary comprehension
 d = {k: k*k for k in range(10) if k != 5 if k != 6}
 
@@ -506,10 +519,12 @@ s = {str(x) + "     " + str(y) + "   " + str(x*y) for x in range(10)
      if x != 6 if x != 5 for y in range(x) if y*x != 8}
 
 [file driver.py]
-from native import l, l2, d, s
+from native import l, l2, l3, l4, d, s
 for a in l:
     print(a)
 print(tuple(l2))
+assert l3 == ['x']
+assert l4 == []
 for k in sorted(d):
     print(k, d[k])
 for a in sorted(s):