Terse diagnostic for never type fallback lint warning involving try operator and placeholder in path · Issue #132358 · rust-lang/rust (original) (raw)

Compiling the following function warns in Rust 1.81 and later:

pub fn foo() -> std::io::Result<()> { [1, 2, 3] .into_iter() .map(|_| -> std::io::Result<_> { Ok(()) }) .collect::<std::io::Result<_>>()?; Ok(()) }

I expected it to compile without warnings, as it did with previous Rust versions. It currently produces this warning:

warning: this function depends on never type fallback being `()`
 --> src/lib.rs:1:1
  |
1 | pub fn foo() -> std::io::Result<()> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
  = help: specify the types explicitly
note: in edition 2024, the requirement `!: FromIterator<()>` will fail
 --> src/lib.rs:5:20
  |
5 |         .collect::<std::io::Result<_>>()?;
  |                    ^^^^^^^^^^^^^^^^^^
  = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default

Playground

What is particularly perplexing about this warning is that I don't understand how the never type is even involved, as nothing in the code appears to diverge.

The current workaround is to add let () = ... before the iteration, which compiles without warnings:

// no warning pub fn foo() -> std::io::Result<()> { let () = [1, 2, 3] .into_iter() .map(|_| -> std::io::Result<_> { Ok(()) }) .collect::<std::io::Result<_>>()?; Ok(()) }

While this workaround works, it feels unnecessary and it's hard to explain and justify.