borrow borrow check logic inspired from rust's NLL TODO hoisting borrow checking lifetime type inference flatten AST