More trouble with tokio::sync::watch

Continuing the discussion from Why isn't there a watch::Sender::new in tokio::sync:

While that problem above can be worked around by using Sender::send_replace, I have run into yet another problem with closed channels, which I would like to explain in the following:

Receiver::borrow_and_update will cause a read-lock. I thus assumed that it's better to check first if the value has changed by using Receiver::has_changed (which uses an atomic operation, see source, which should be cheaper than acquiring/releasing a read-lock?).

Unfortunately, the has_changed method will fail if the Sender has been dropped (and it's not even possible to clone the Sender and store the clone somewhere else):

use tokio::sync::watch;

fn main() {
    let (tx, mut rx) = watch::channel(1);
    tx.send_replace(2);
    //drop(tx); // if `Sender` is dropped, `has_changed` becomes useless:
    if rx.has_changed().unwrap_or(false) {
        println!("{}", rx.borrow_and_update().clone());
    }
}

(Playground)

Given a scenario where the Sender might be dropped at any point but I still want to retrieve the last sent value, I seem to have to work around this problem in a complicated way:

use tokio::sync::watch;

fn main() {
    let (tx, mut rx) = watch::channel(1);
    let mut closed = false;
    tx.send_replace(2);
    drop(tx);
    for _ in 0..3 {
        let changed = match closed {
            false => rx.has_changed(),
            true => Ok(false),
        };
        let close = changed.is_err();
        if changed.unwrap_or(true) {
            println!("{}", rx.borrow_and_update().clone());
        }
        if close {
            closed = true;
        }
    }
}

(Playground)

Here, I ensure that if the channel is closed, I will borrow_and_update exactly one more time (such that I don't miss any potential update). It is unwieldy and also invokes borrow_and_update once without need if there wasn't any change (but the Sender was just dropped).

How can I solve this problem in a better way?

I guess the check for a closed channel in has_changed (source) could be easily omitted? Perhaps Tokio could/should have an alternative method which doesn't include this check? This would simplify use cases where the Receiver must not accidentally miss sent values.


Update: Re-thinking about this, I think I can (and should) modify my receiving task such that it terminates when the struct that's keeping the Sender is dropped. Thus, I think I no longer have this problem myself.