I think there is an argument to be made that it should either panic or cause the future to never be ready ever again in case of an overflow in Interval::poll_tick. The overflow only happens when one of the following conditions is true:
We are close to the latest time representable by Instant. In this case Instant::far_future will panic anyway and Instant::MAX would wait too little time.
We are already after the latest time representable by Instant. In this case it is impossible to obtain an Instant anyway, so there is no safe way to handle this. The only options are to panic or have the future never be ready ever again.
The period is ridiculously large. This is likely a bug in the program that uses Interval, thus warranting a panic. Even if it is not a bug, if Instant::MAX is used as next time to be ready, on the next tick the first condition would trivially be true. And using Instant::far_future would wait too little time.
I think you have some good points, maybe the Tokio code code be improved. But I have a few questions.
I don't think this is a given. Especially since some OSes apparently can't represent Instants 100 years away. I can imagine a program that calculates the next time it needs to do something and that happens to be very far in the future. In this case the best behaviour is likely to just wait forever. For example maybe it is calculating the next instant of an event on an astronomical timescale. Just because an event is incredibly unlikely to occur before a program stops running doesn't mean that waiting for it is a bug.
I think the best solution for sleep(std::time::Duration::MAX) is probably to keep the future alive but never call it. Panic if Instant::now reaches Instant::MAX. This behaves the same as all other sleeps, keeping the future alive until the specified time, but panics only in the unlikely condition that the process does run for as long as the clock can function. At this point I don't think there is any reasonable behaviour for a program that is using timers, so just panic. This means that you never run a timer too early but you also don't panic upfront just in case the incredibly unlikely situation of Instant::now() hitting Instant::MAX occurs.
This is also an interesting use case for Instant::MAX, you can monitor Instant::MAX - Instant::now() to figure out how long your process has before timers completely break.
I don't know what you mean here. What is "the first condition"? And yes Instant::far_future would wait too little, that is the reason why it is a hack and Instant::MAX could improve the code.
That is a good option, but not what tokio does. It doesn't need Instant::MAX either. Just never registering an instant to be woken up again would be enough.
Being very close to the latest time representable by an Instant. Aka the first bullet point I listed.
Even Instant::MAX would wait too little in that case.
Only if you ever actually returned, if you guarantee to panic at Instant::MAX then you are fine. Basically it lets you continue to store futures how you normally would but with a clear value that is the "end of time" as far as the scheduler is concerned.
You can check this condition specifically and just do Box::leak or whatever, but I'm not convinced that it is better.