(&self, inst: Inst, errors: &mut VerifierErrors)
| 1301 | } |
| 1302 | |
| 1303 | fn typecheck(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult { |
| 1304 | let inst_data = &self.func.dfg.insts[inst]; |
| 1305 | let constraints = inst_data.opcode().constraints(); |
| 1306 | |
| 1307 | let ctrl_type = if let Some(value_typeset) = constraints.ctrl_typeset() { |
| 1308 | // For polymorphic opcodes, determine the controlling type variable first. |
| 1309 | let ctrl_type = self.func.dfg.ctrl_typevar(inst); |
| 1310 | |
| 1311 | if !value_typeset.contains(ctrl_type) { |
| 1312 | errors.report(( |
| 1313 | inst, |
| 1314 | self.context(inst), |
| 1315 | format!( |
| 1316 | "has an invalid controlling type {ctrl_type} (allowed set is {value_typeset:?})" |
| 1317 | ), |
| 1318 | )); |
| 1319 | } |
| 1320 | |
| 1321 | ctrl_type |
| 1322 | } else { |
| 1323 | // Non-polymorphic instructions don't check the controlling type variable, so `Option` |
| 1324 | // is unnecessary and we can just make it `INVALID`. |
| 1325 | types::INVALID |
| 1326 | }; |
| 1327 | |
| 1328 | // Typechecking instructions is never fatal |
| 1329 | let _ = self.typecheck_results(inst, ctrl_type, errors); |
| 1330 | let _ = self.typecheck_fixed_args(inst, ctrl_type, errors); |
| 1331 | let _ = self.typecheck_variable_args(inst, errors); |
| 1332 | let _ = self.typecheck_return(inst, errors); |
| 1333 | let _ = self.typecheck_special(inst, errors); |
| 1334 | |
| 1335 | Ok(()) |
| 1336 | } |
| 1337 | |
| 1338 | fn typecheck_results( |
| 1339 | &self, |
no test coverage detected