MCPcopy Create free account
hub / github.com/python/mypy / OpChecker

Class OpChecker

mypyc/analysis/ircheck.py:242–498  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

240
241
242class OpChecker(OpVisitor[None]):
243 def __init__(self, parent_fn: FuncIR) -> None:
244 self.parent_fn = parent_fn
245 self.errors: list[FnError] = []
246
247 def fail(self, source: Op, desc: str) -> None:
248 self.errors.append(FnError(source=source, desc=desc))
249
250 def check_control_op_targets(self, op: ControlOp) -> None:
251 for target in op.targets():
252 if target not in self.parent_fn.blocks:
253 self.fail(source=op, desc=f"Invalid control operation target: {target.label}")
254
255 def check_type_coercion(self, op: Op, src: RType, dest: RType) -> None:
256 if not can_coerce_to(src, dest):
257 self.fail(
258 source=op, desc=f"Cannot coerce source type {src.name} to dest type {dest.name}"
259 )
260
261 def check_compatibility(self, op: Op, t: RType, s: RType) -> None:
262 if not can_coerce_to(t, s) or not can_coerce_to(s, t):
263 self.fail(source=op, desc=f"{t.name} and {s.name} are not compatible")
264
265 def expect_float(self, op: Op, v: Value) -> None:
266 if not is_float_rprimitive(v.type):
267 self.fail(op, f"Float expected (actual type is {v.type})")
268
269 def expect_non_float(self, op: Op, v: Value) -> None:
270 if is_float_rprimitive(v.type):
271 self.fail(op, "Float not expected")
272
273 def expect_primitive_type(self, op: Op, v: Value) -> None:
274 if not isinstance(v.type, RPrimitive):
275 self.fail(op, f"RPrimitive expected, got {type(v.type).__name__}")
276
277 def visit_goto(self, op: Goto) -> None:
278 self.check_control_op_targets(op)
279
280 def visit_branch(self, op: Branch) -> None:
281 self.check_control_op_targets(op)
282
283 def visit_return(self, op: Return) -> None:
284 self.check_type_coercion(op, op.value.type, self.parent_fn.decl.sig.ret_type)
285
286 def visit_unreachable(self, op: Unreachable) -> None:
287 # Unreachables are checked at a higher level since validation
288 # requires access to the entire basic block.
289 pass
290
291 def visit_assign(self, op: Assign) -> None:
292 self.check_type_coercion(op, op.src.type, op.dest.type)
293
294 def visit_assign_multi(self, op: AssignMulti) -> None:
295 for src in op.src:
296 assert isinstance(op.dest.type, RArray)
297 self.check_type_coercion(op, src.type, op.dest.type.item_type)
298
299 def visit_load_error_value(self, op: LoadErrorValue) -> None:

Callers 1

check_func_irFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…