1212from mypy .nodes import (
1313 ARG_POS ,
1414 CallExpr ,
15+ DictionaryComprehension ,
1516 Expression ,
1617 GeneratorExpr ,
1718 Lvalue ,
1819 MemberExpr ,
20+ NameExpr ,
1921 RefExpr ,
2022 SetExpr ,
2123 TupleExpr ,
2830 IntOp ,
2931 LoadAddress ,
3032 LoadMem ,
33+ RaiseStandardError ,
3134 Register ,
3235 TupleGet ,
3336 TupleSet ,
@@ -229,6 +232,9 @@ def set_item(item_index: Value) -> None:
229232
230233
231234def translate_list_comprehension (builder : IRBuilder , gen : GeneratorExpr ) -> Value :
235+ if raise_error_if_contains_unreachable_names (builder , gen ):
236+ return builder .none ()
237+
232238 # Try simplest list comprehension, otherwise fall back to general one
233239 val = sequence_from_generator_preallocate_helper (
234240 builder ,
@@ -251,7 +257,30 @@ def gen_inner_stmts() -> None:
251257 return builder .read (list_ops )
252258
253259
260+ def raise_error_if_contains_unreachable_names (
261+ builder : IRBuilder , gen : GeneratorExpr | DictionaryComprehension
262+ ) -> bool :
263+ """Raise a runtime error and return True if generator contains unreachable names.
264+
265+ False is returned if the generator can be safely transformed without crashing.
266+ (It may still be unreachable!)
267+ """
268+ if any (isinstance (s , NameExpr ) and s .node is None for s in gen .indices ):
269+ error = RaiseStandardError (
270+ RaiseStandardError .RUNTIME_ERROR ,
271+ "mypyc internal error: should be unreachable" ,
272+ gen .line ,
273+ )
274+ builder .add (error )
275+ return True
276+
277+ return False
278+
279+
254280def translate_set_comprehension (builder : IRBuilder , gen : GeneratorExpr ) -> Value :
281+ if raise_error_if_contains_unreachable_names (builder , gen ):
282+ return builder .none ()
283+
255284 set_ops = builder .maybe_spill (builder .new_set_op ([], gen .line ))
256285 loop_params = list (zip (gen .indices , gen .sequences , gen .condlists , gen .is_async ))
257286
0 commit comments