Skip to content

ACP: impl From<Infallible> for io::Error #86

@Kixunil

Description

@Kixunil

Proposal

Problem statement

Generic code sometimes needs to unify error types. This may happen in combinators or specialization-like wrappers. While Infallible should be obviously, trivially convertible to io::Error, the impl is not available.

Motivation, use-cases

My current use case (simplified)

pub struct HexWriter<W: HexWrite>(W);

/// Abstracts over fmt::Write and io::Write
pub trait HexWrite {
    type Error;
    fn write_byte(&mut self, byte: u8) -> Result<(), Self::Error>;
}

pub struct IoWriter<W: io::Write>(W);

impl<W: io::Write> HexWrite for IoWriter<W> { type Error = io::Error; /* ... */ }

/// Direct impl avoids dynamic dispatch of formatting and provides provably non-failing errors
impl HexWrite for String { type Error = Infallible; /* ... */ }


// Ideally, this would work for both HexWriter<String> and HexWriter<IoWriter<W>>:
impl<W> io::Write for HexWriter<W> where W: HexWrite, W::Error: Into<io::Error> { /* ... */ }

Potential other use cases

I vaguely remember doing something like this in the past, I think it was related to futures or some IO:

pub enum Error<A, B> {
   ErrorA(A),
   ErrorB(B),
}

impl<A, B> Error<A, B> {
    pub fn unify<E>(self) -> E where A: Into<E>, B: Into<E> {
        match self {
            ErrorA(a) => a.into(),
            ErrorB(b) => b.into(),
        }
    }
}

This allows unifying error types of different operations. If one of the operations is infallible and the other may return io::Error unify currently can not be used even though it looks like it should.

Solution sketches

Proposed solution: Impl conversion by matching on self, I don't see any downsides besides few added lines of code
Alternative solution 1: impl<T> From<Infallible> for T - this is probably far away due to overlap with impl<T> From<T> for T; the proposed solution already provides value and can be replaced with this alternative later without breaking anything
Alternative solution 2: do nothing, users can have their own IntoIoError trait (my current workaround) - this needlessly duplicates and complicates users code, adding a few lines to std seems to be a better trade-off.

Links and related work

PR implementing this

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions