Skip to content

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

Closed as not planned
Closed as not planned
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions