import { VType } from "../vtype.ts"; import { Fn, Local, Mir, replaceBlockSrcs, RValue } from "./mir.ts"; export function makeMoveCopyExplicit(mir: Mir) { for (const fn of mir.fns) { for (const local of fn.locals) { new LocalExpliciter(fn, local).pass(); } } } class LocalExpliciter { private copyable: boolean; public constructor(private fn: Fn, private local: Local) { this.copyable = copyableIsType(local.vtype); } public pass() { for (const block of this.fn.blocks) { replaceBlockSrcs(block, (src) => this.explicitSrc(src)); } } private explicitSrc(src: RValue): RValue { if (src.type !== "local") { return src; } return this.copyable ? { type: "copy", id: src.id } : { type: "move", id: src.id }; } } function copyableIsType(vtype: VType): boolean { switch (vtype.type) { case "error": case "unknown": throw new Error(); case "null": case "int": case "bool": case "string": case "ref": case "ref_mut": case "ptr": case "ptr_mut": return true; case "array": case "struct": case "fn": return false; case "generic": return false; case "generic_spec": throw new Error(); } }