pub class Rc : Drop, Copy class Inner(t: T) mut count = 1 end inner: &weak Inner = Null pub ctor(t: T) inner = Inner(t) end ctor(parent: &Self) parent.inner++ inner = &weak parent.inner end pub fn copy() -> Self Self(self) end impl fn drop(self) if inner.upgrade() is Some(inner) then inner.count-- if inner.count == 0 then drop inner end else throw Exception('rc.inner could not be converted from a weak reference') end end end class Game(player: Player) end class Player pub mut game: &weak Game = Null end fn circular() let player = Player() let game = Game(player) expectThrows(EmptyWeakReferenceException) { player.game.upgrade() } player.game = &weak game expectDoesNotThrow { player.game.upgrade() } end class Board pub fn flip() println 'Flipped!' end end class ChessGame(pub board: rc Board) end class ChessPlayer(pub board: rc Board) end fn getGameAndPlayer() -> (ChessGame, ChessPlayer) let board = rc Board() // Rc count is 1 let game = ChessGame(board) // Rc copied, count is 2 let player = ChessPlayer(board) // Rc copied, count is 3 (game, player) // initial Rc dropped before fn return, count now 2 end fn playChess() let (game, player) = getGameAndPlayer() // Rc count is 2 let board = game.board // Copy, so count is now 3 board.flip() drop board // count now 2 drop game // count now 1 drop player // count now 0, board memory finally dropped end