function setmt__gc(t, mt) local prox = newproxy(true) local mtcopy = {} for k, v in pairs(mt) do mtcopy[k] = v end getmetatable(prox).__gc = function() mtcopy.__gc(t) end mtcopy[prox] = true return setmetatable(t, mtcopy) end local iscollected = false function gctest(self) iscollected = true print("cleaning up:", self) end local mt2 = {__gc = gctest} test = setmt__gc({}, mt2) collectgarbage() assert(not iscollected) test = nil collectgarbage() assert(iscollected)