Skip to content

I/O safety breaks existing code #89955

Closed
Closed
@sunfishcode

Description

@sunfishcode

As reported here, the I/O safety feature introduces a breaking change.

Reduced standalone testcase (playground link):

use std::os::unix::io::FromRawFd;
use std::fs::File;

pub fn create_fd<F: FromRawFd>() -> F {
    todo!()
}

fn main() {
    let _f = File::from(create_fd());
}
error[E0283]: type annotations needed
   --> src/main.rs:9:14
    |
9   |     let _f = File::from(create_fd());
    |              ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the trait `From`
    |
    = note: cannot satisfy `File: From<_>`
note: required by `from`
   --> /.../lib/rustlib/src/rust/library/core/src/convert/mod.rs:371:5
    |
371 |     fn from(_: T) -> Self;
    |     ^^^^^^^^^^^^^^^^^^^^^^

It's possible to change the code to avoid the error, for example by changing the let _f = ... line to either of:

    let _f = create_fd::<File>();
    let _f: File = create_fd(); 

or, once I/O safety is stabilized, by changing create_fd to return OwnedFd instead of F: FromRawFd. The reporter also reported that they've already fixed their own code. Nevertheless, it is breakage observed in real-world code.

The problem is caused by I/O safety adding an impl From<OwnedFd> for File. We added these From impls as an alternative to adding a new FromFd trait. However, this means that File now has multiple From impls for types that implement AsRawFd, so one can no longer do File::from(create_fd()) where create_fd is defined like fn create_fd<F: FromRawFd>() -> F, because it's now ambiguous which type it should use for F.

So the questions here are:

  • Is this breakage severe enough to block stabilization for I/O safety?
  • If so, is there a way to fix it other than going back to adding a FromFd trait?

Metadata

Metadata

Assignees

Labels

T-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions