Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rust, how to template functions returning `impl Iterator<Item = String>`

Tags:

rust

I am attempting template some functions and finding it difficult to template functions returning Iterators. They occur as syntax errors

struct A;
impl A {
    fn x(&self) -> impl Iterator<Item = String> {
        todo!()
    }
}

The syntax error is:

Compiling playground v0.0.1 (/playground)
error[E0277]: `()` is not an iterator
 --> src/lib.rs:3:20
  |
3 |     fn x(&self) -> impl Iterator<Item = String> {
  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
  |
  = help: the trait `Iterator` is not implemented for `()`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
like image 684
George Avatar asked Feb 05 '26 00:02

George


2 Answers

The standard library's Empty::new() is available to provide a template default. However, the standard approach is to use the provided constructor function: std::iter::empty()

struct A;
impl A {
    fn x(&self) -> impl Iterator<Item = String> {
        std::iter::empty()
    }
}
like image 185
George Avatar answered Feb 06 '26 13:02

George


The reason that this doesn't work is that todo!() returns ! (aka never). Since ! cannot have a value, it can be reconciled to any other type; that is, it's concrete type is inferred based on assignment, similar to a generic return type, T. But impl Iterator isn't concrete either, so each one is relying on the other for type inferrence, creating a kind of circular reference.

You can fix this by making the body a concrete iterator type, as in George's answer, which I won't duplicate here. Alternatively you can make the return type concrete. For example:

use std::iter::Empty;
fn x(&self) -> Empty<String> {
    std::iter::empty()
}

Type inference can be convenient and can reduce the amount of noise in type annotations, but you need to provide sufficient information, so the type can be inferred in one direction or the other.

like image 41
Peter Hall Avatar answered Feb 06 '26 12:02

Peter Hall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!