I feel like a better comparison would be to use std::span (C++20) to mimic Rust's slice. Otherwise you might be tricked into thinking that adding
// hey don't pass in a temporary
auto make_appender(std::vector<int>&& suffix) = delete;
(which turns the provided code into a compiler error under both g++ and clang++) is adequate to prevent the immediate class of issues (namely, C++ allows const Foo& and Foo&& to bind to temporaries).
Meanwhile, it's really really easy to make std::span dangle:
> Nobody would write a make_appender that takes a span argument, because it makes no sense.
I don't agree with that. If you can guarantee that the data pointed to by the span will outlive your appender, then it's safe. And if you don't actually want to transfer ownership or incur the overhead of a copy, and you don't care if your input is a vector or an array, then it's the correct abstraction.
Replace std::span with std::weak_ptr (or a raw pointer), and replace the closure with a class (e.g. a tree where each node has a weak pointer to its parent), and tell me again that nobody would ever write that code. It's fundamentally the same concept: if your ownership model isn't ironclad, or if any of your assumptions are ever violated, then you can run into use-after-free.
Meanwhile, it's really really easy to make std::span dangle: