{"record":{"id":"a0097561584b8e6f","repo":"FuelLabs/sway","slug":"pushall-and-popall-don-t-belong-in-control-flo","errorCode":null,"errorMessage":"`PushAll` and `PopAll` don't belong in control flow ops since they're not about control flow","messagePattern":"`PushAll` and `PopAll` don't belong in control flow ops since they're not about control flow","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs","lineNumber":423,"sourceCode":"            // This is a concrete op, size is fixed.\n            Either::Left(_) => 1,\n\n            // Worst case for jump is 2 opcodes, and 3 for calls.\n            Either::Right(Jump { ref type_, .. }) => match type_ {\n                JumpType::Unconditional => 2,\n                JumpType::NotZero(_) => 2,\n                JumpType::Call => 3,\n            },\n            Either::Right(JumpToAddr(..)) => 1,\n            Either::Right(ReturnFromCall { .. }) => 1,\n            Either::Right(Comment) => 0,\n            Either::Right(DataSectionOffsetPlaceholder) => {\n                // If the placeholder is 32 bits, this is 1. If 64, this should be 2. We use LW\n                // to load the data, which loads a whole word, so for now this is 2.\n                2\n            }\n            Either::Right(ConfigurablesOffsetPlaceholder) => 2,\n            Either::Right(PushAll(_)) | Either::Right(PopAll(_)) => unreachable!(\n                \"`PushAll` and `PopAll` don't belong in control flow ops \\\n                        since they're not about control flow\"\n            ),\n        }\n    }\n\n    // Actual size of an instruction.\n    //\n    // **Note that this return incorrect values for far jumps, they must be handled separately.**\n    // The return value is in concrete instructions, i.e. units of 4 bytes.\n    fn instruction_size_not_far_jump(op: &AllocatedAbstractOp, data_section: &DataSection) -> u64 {\n        use ControlFlowOp::*;\n        match op.opcode {\n            Either::Right(Label(_)) => 0,\n\n            // A special case for LoadDataId which may be 1 or 2 ops, depending on the source size.\n            Either::Left(AllocatedInstruction::LoadDataId(_, ref data_id)) => {\n                let has_copy_type = data_section.has_copy_type(data_id).expect(","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/FuelLabs/sway/blob/dad95cc42b0383b4e3bacdeda9766565aa584a92/sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs#L405-L441","documentation":"This unreachable! guards worst_case_instruction_size, which computes the worst-case concrete instruction count for each allocated abstract op. PushAll and PopAll are abstract stack-management ops, not control-flow ops, so they must never appear in the ControlFlowOp arm of this match. Reaching this panic means an abstract instruction set was built with PushAll/PopAll ops inside the control-flow op representation, i.e. an internal codegen misclassification bug.","triggerScenarios":"Thrown at sway-core/src/asm_generation/fuel/allocated_abstract_instruction_set.rs:423 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Find where the abstract op was classified as a ControlFlowOp and move PushAll/PopAll to the plain (concrete) instruction category","Ensure lowering passes never wrap PushAll/PopAll in Either::Right (control flow) — they should be Either::Left concrete ops","Add a debug-time classification check when AllocatedAbstractOp values are constructed so misclassification is caught at creation rather than during size computation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"dad95cc42b0383b4e3bacdeda9766565aa584a92","analyzedAt":"2026-09-04T20:02:14.068Z","contentChangedAt":"2026-09-04T20:02:14.068Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}