# Would it make sense for never to implement Iterator?

**URL:** <https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732>\
**Category:** libs\
**Created:** [October 30, 2026, 1:09pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732 "2026-10-30T13:09:13Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sawyer47](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sawyer47/32/13467_2.png) [@Sawyer47](https://internals.rust-lang.org/u/Sawyer47)\
**Post date:** [October 30, 2026, 1:09pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/1 "2026-10-30T13:09:13Z")

</div>

After reading [nightly documentation](https://doc.rust-lang.org/nightly/std/primitive.never.html) for the `never` type I started wondering why `!` does not implement the `Iterator` trait.

The documentation states:

> In general, if a trait only has methods taking a self parameter (or &self, or an argument of type Self, etc.), consider implementing it for !

`Iterator` trait meets this criterion. There is also an associated type, but the `Not` trait has an associated type as well and `!` implements `Not`. In both cases `!` seems like the most obvious choice for the item type.

I tried implementing Iterator for an uninhabited enum and it looks like it should be possible for `!` as well.

```rust
enum Void {}

impl Iterator for Void {
    type Item = Void;

    fn next(&mut self) -> Option<Self::Item> {
       match *self {}
       // could also be None, but it does not matter, right?
    }
}

fn void_panic() -> Void {
    panic!()
}

fn my_foo() -> impl Iterator<Item=u32> {
    void_panic()
    // error[E0271]: expected `Void` to be an iterator that yields `u32`, but it yields `Void`
    // instead of
    // error[E0277]: `Void` is not an iterator
}

fn main() {
    my_foo();
    for x in void_panic() {
    // warning: unreachable expression
    // instead of
    // error[E0277]: `Void` is not an iterator
    }
}

```

Am I missing some potential problem? Is there a reason why `!` does not implement `Iterator`

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [October 30, 2026, 1:20pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/2 "2026-10-30T13:20:43Z")

</div>

The problem is that one could implement it only for one single `Item` type, so which one to pick?

IMHO, what could possibly be more sensible for this use case is for `impl Trait`\[1\] return types in functions that diverge to create some fresh uninhabited `!`-like anonymous types on the fly which then implement the required trait bound; maybe even just as a fallback.

* * *

1. at least for traits like `Iterator` where every method has a `self` argument that makes them uncallable for uninhabited `Self` types

---

<div class="post-metadata">

**Author:** ![JarredAllen](https://avatars.discourse-cdn.com/v4/letter/j/a183cd/32.png) [@JarredAllen](https://internals.rust-lang.org/u/JarredAllen)\
**Post date:** [October 30, 2026, 2:31pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/3 "2026-10-30T14:31:31Z")

</div>

Or, I have no idea how hard this would be to implement, but if we make `!: Iterator<!>`, then extend fallback such that `impl Iterator<!>` can coerce to an iterator over any type. That would solve this problem of which item type to use.

---

<div class="post-metadata">

**Author:** ![Sawyer47](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sawyer47/32/13467_2.png) [@Sawyer47](https://internals.rust-lang.org/u/Sawyer47)\
**Post date:** [October 30, 2026, 3:29pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/4 "2026-10-30T15:29:18Z")

</div>

Oh, I think I understand the problem now. In other words, it would make sense for `!` to implement Iterator for all possible `Item` types, not just `!`?

If so, doesn't the same logic applies to `std::ops::Not`? If would make sense for `!` to implement `Not` for all possible associated `Output` types. It is just less problematic in practice as it is unlikely to see a function returning `impl Not<Output=_some_type_>`.

---

<div class="post-metadata">

**Author:** ![Morgane55440](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/morgane55440/32/14179_2.png) [@Morgane55440](https://internals.rust-lang.org/u/Morgane55440)\
**Post date:** [October 30, 2026, 4:32pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/5 "2026-10-30T16:32:17Z")

</div>

> [@Sawyer47](#):
>
> it would make sense for `!` to implement Iterator for all possible `Item` types, not just `!`?

that is simply not possible any one trait/type pair can only have one associated type. what would be needed would be something like

```rs
struct TypedNever<T>(!, PhantomData<T>)

```

which could be used to decide custom associated types for such traits. though that wouldn't be perfect

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 30, 2026, 5:18pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/6 "2026-10-30T17:18:40Z")

</div>

A case that's often disappointing is that stuff like this doesn't work:

```rust
fn foo() -> impl Iterator<Item = i32> { todo!() }
```

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [October 30, 2026, 6:05pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/7 "2026-10-30T18:05:59Z")

</div>

> [@Sawyer47](#):
>
> In other words, it would make sense for `!` to implement Iterator for all possible `Item` types, not just `!`?

It does not make sense, but it would be useful.

In other words, a lot of code requires `impl Iterator<Item = SomeSpecificT>`, so for the implementation of `Iterator` for `!` to be useful it would have to support all those cases.

However it does not make sense because `<! as Iterator>::Item` is a single type, so which one is it?

Even if you make `!` coercible to something else that implements `Iterator`\<Item = SomeSpecificT\>` it still won't work because coercions are not attempted when a generic type is expected.

> [@Sawyer47](#):
>
> If so, doesn't the same logic applies to `std::ops::Not`? If would make sense for `!` to implement `Not` for all possible associated `Output` types.

Yes, the implementation of `Not` for `!` is not ideal and has the same issues as an hypothetic implementation of `Iterator` for `!`

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [October 30, 2026, 6:58pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/8 "2026-10-30T18:58:22Z")

</div>

For `Iterator` specifically, I use `[].into_iter()`.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 30, 2026, 9:06pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/9 "2026-10-30T21:06:24Z")

</div>

Yeah, but if you still want the panic then you have to "hide" it to avoid unused lints, e.g.

```rust
if true { todo!() }
[].into_iter()

```

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [October 31, 2026, 4:28am UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/10 "2026-10-31T04:28:03Z")

</div>

[Reduce `unreachable-code` churn after `todo!()` by llogiq · Pull Request #149543 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/pull/149543) aims to make this better, by not warning on unreachable code that is unreachable because of a `todo!()`.

---

<div class="post-metadata">

**Author:** ![idanarye](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/idanarye/32/3346_2.png) [@idanarye](https://internals.rust-lang.org/u/idanarye)\
**Post date:** [November 1, 2026, 2:16pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/11 "2026-11-01T14:16:14Z")

</div>

I think the problem is that Rust does not have type hierarchy\[1\], and thus trait bounds cannot define covariance and contravariance. Because of that `!` cannot be a "true" _Bottom Type_ like full OOP languages can have - it just have lots of special-casing to make it behave like one.

* * *

1. Traits and lifetimes have hierarchies - but not types.

---

<div class="post-metadata">

**Author:** ![zirconium-n](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zirconium-n/32/9078_2.png) [@zirconium-n](https://internals.rust-lang.org/u/zirconium-n)\
**Post date:** [November 2, 2026, 5:30am UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/12 "2026-11-02T05:30:49Z")

</div>

I wonder why did we make `Item` an associated type instead of a type parameter of `trait Iterator`? One possible reason I can think of is making `.collect()` works better, but are there any other reasons?

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [November 2, 2026, 6:54am UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/13 "2026-11-02T06:54:14Z")

</div>

Intuitively it makes sense that if something can be iterated over it will yield one type of items, while if it were a generic it would be kinda confusing that you can iterate in a way and get one type of items or iterate in another way and get a different type of items.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [November 2, 2026, 1:02pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/14 "2026-11-02T13:02:51Z")

</div>

> [@JarredAllen](#):
>
> if we make `!: Iterator<!>`, then extend fallback such that `impl Iterator<!>` can coerce to an iterator over any type

I have a somewhat harder time imagining a language design principle based on which to coerce any `impl Iterator<Item = !>` to a (new, anonymous, wrapping) type implementing `impl Iterator<Item = T>` for any (particular) other type; compared to my previously mentioned idea of coercing `!` to an (new, anonymous, uninhabited) type implementing `impl Iterator<Item = T>`.

Both features would require some amount of introspection into the method signature of the trait\[1\] but the latter seems conceptually simpler IMO (and more narrow) as it only deals with uninhabited types.

I suppose that @idanarye now mentioned above sounds relevant though

> [@idanarye](#):
>
> trait bounds cannot define covariance and contravariance

and I think indeed such a coercion of an `impl Iterator<Item = !>` to an `impl Iterator<Item = T>` sounds - arguably - like something that might come out of any “trait variance” design ideas, after all.

Specifically, similar coercions are sometimes desirable for coercing between `impl Fn…` kind of types (e.g. in a manner mirroring the variances of `fn` pointer types), in particular the `Output` type of `FnOnce` is comparable to the `Item` type of `Iterator`.\[2\]

* * *

1. and based on language design choices presumably also an opt-in 

2. On the other hand, as long as `Fn…` traits are not user-implementable yet, I can also imagine other designs to achieve their variance that don’t involve coercing to anonymous wrapper types, but instead some way of promising through the trait system the existence of other generic instantiations of the _same_ closure type.  
  
(This could allow achieving _true subtyping_ between the original and coerced closure types, in cases where the argument types also were subtypes. Note that `!` is not actually in a true subtyping relation to other types either, further complicating the story in any case, if it’s meant to apply to `!` -\> `T` coercions for the `Output` type.)

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [November 2, 2026, 1:20pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/15 "2026-11-02T13:20:19Z")

</div>

Well, we do have that, but adapters are used instead of direct iteration (cf. `String::chars()` and `String::lines()`). Even when direct iteration was used, it proved problematic (e.g., `Range` and friends).

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [November 2, 2026, 7:12pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/16 "2026-11-02T19:12:37Z")

</div>

> [@zirconium-n](#):
>
> I wonder why did we make `Item` an associated type instead of a type parameter of `trait Iterator`?

Because otherwise this doesn't compile:

```rust
for x in my_iter {
    println!("{}", x);
}

```

as there's nothing in that code that would pick the item type.

(Well, perhaps modulo the one-impl rule but that's super fragile and never a good thing to depend on if you can avoid it.)

And similarly for all kinds of other similar situations. `it.filter(|x| x.foo > 10)` wouldn't work because that closure wouldn't define the element type and field access needs to know the type, for example, but does with the associated type today because there's only the one possibility once the `it` type is known.

---

<div class="post-metadata">

**Author:** ![ais523](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@ais523](https://internals.rust-lang.org/u/ais523)\
**Post date:** [November 2, 2026, 11:23pm UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/17 "2026-11-02T23:23:29Z")

</div>

There are cases in practice where a type wants to implement `Iterator` (or at least `IntoIter`) two different ways. `&str` is a good example, as an iteration over it can plausibly return either `u8` or `char` (Rust currently deals with this situation by using `.bytes()` and `.chars()` methods to return an appropriate iterable rather than implementing `Iterator` on `&str` directly). So it doesn't seem too ridiculous for a type to want to implement `Iterator` for two different element types.

For what it's worth, I consider associated types to be one of the most dangerous features of Rust, in the sense that it is hard to gain confidence that the compiler implements them correctly (and yet if the compiler implements them incorrectly, it can lead to unsoundness in safe code). The alternative would be to make them type parameters instead, using `Iterator<T>` rather than `Iterator<Item=T>`, and in that case it would be plausible to `impl<T> Iterator<T> for !`.

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [November 3, 2026, 5:46am UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/18 "2026-11-03T05:46:36Z")

</div>

> [@ais523](#):
>
> `&str` is a good example, as an iteration over it can plausibly return either `u8` or `char`

I can see this being an argument for `IntoIterator` being generic (even though I feel that being explicit is better), but not `Iterator`.

If you model this using a generic `Iterator` implementation then it means you can mix the `u8` and `char` iteration: you could call `next` to get the next `u8` (possibly moving in the middle of a `char`) and then `next` to get the next `char` (what would that mean then?).

---

<div class="post-metadata">

**Author:** ![Ddystopia](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ddystopia/32/10915_2.png) [@Ddystopia](https://internals.rust-lang.org/u/Ddystopia)\
**Post date:** [November 3, 2026, 10:46am UTC](https://internals.rust-lang.org/t/would-it-make-sense-for-never-to-implement-iterator/24732/19 "2026-11-03T10:46:09Z")

</div>

It works poorly when some other branch has already defined a concrete type 😅
