Stable specialization in Rust

22 points by morj


addison

Oh man, every time I pull stuff like this, compiler devs yell at me. e.g.: https://github.com/rust-lang/rust/issues/132442#issuecomment-2640229040

robinhundt

Wonderfully cursed!

Some additional explanation:

This works by defining a generic method is_send<T>() -> bool that returns true if the type parameter implements the Send trait and false otherwise. In "normal" and stable Rust, this function wouldn't be possible to implement, as it requires the unstable specialization feature. However, this feature is used internally in the std library for performance reasons. One case is the Fuse iterator adapter, whose specialization enabled optimization is guaranteed by the documentation, i.e., fusing an already fused iterator is a no-op.

We now define a generic iterator Checker<T> that implements a counter inside its next method and returns None. We conditionally implement FusedIterator for Checker<T> if T implements Send. Then we instantiate this iterator with the type T passed to is_send and .fuse() it, call .next() twice, and check whether the counter is 2. We have two cases:

Case 1: T is not Send
Because T is not Send, we don't implement FusedIterator for Checker<T>. The Fuse adapter is not reduced to a no-op. Therefore, it operates as usual. It calls the Checker::next function once, notes that it returned None, and afterwards always returns None without calling the internal Checker::next. Therefore the counter is incremented once, and the function returns 1 == 2 (false).

Case 2: T is Send
Because T: Send, we implement FusedIterator for Checker<T>. In this case, the docs guarantee that the Fuse<Checker<T>> Wrapper is a no-op, meaning it simply delegates to the internal next method. Therefore, Checker<T>::next is called twice, the counter is 2, we return 2 == 2 (true) and know that T is Send.

Like the author, I would not endorse using this :D I'm curious whether the documented no-op behavior of the Fuse Wrapper is actually guaranteed, or if this is an oversight.