Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::io::copy should take Read and Write traits by value #105643

Closed
est31 opened this issue Dec 13, 2022 · 6 comments
Closed

std::io::copy should take Read and Write traits by value #105643

est31 opened this issue Dec 13, 2022 · 6 comments
Labels
disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@est31
Copy link
Member

est31 commented Dec 13, 2022

This was suggested by @alexcrichton way back in 2015:

mod std::io {
    fn copy<R: Read, W: Write>(r: R, w: W) -> io::Result<u64> { ... }
}

but it wasn't done as it regressed 3 (root) crates in a crater run. Still, ideally if the API breakage policy is ever revisited, it would be better to take Read and Write by-value, as a type impl'ing Read transmits this property to &mut references of it.

@rustbot label T-libs-api rust-2-breakage-wishlist

@rustbot
Copy link
Collaborator

rustbot commented Dec 13, 2022

Error: Label rust-2-breakage-wishlist can only be set by Rust team members

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

@Noratrieb Noratrieb added the rust-2-breakage-wishlist In the wishlist of breaking changes that requires rust 2.0 label Dec 14, 2022
@est31
Copy link
Member Author

est31 commented Dec 15, 2022

FTR this is the error I'm getting if I modify the copy function on a local toolchain based off current master and try to build tar 0.3.1:

error[E0382]: use of moved value: `self`
   --> src/entry.rs:134:48
    |
134 |             if try!(io::copy(self, &mut f)) != self.size {
    |                              ----              ^^^^^^^^^ value used here after move
    |                              |
    |                              value moved here
    |
    = note: move occurs because `self` has type `&mut EntryFields<'_>`, which does not implement the `Copy` trait

error[E0382]: borrow of moved value: `self`
   --> src/entry.rs:145:28
    |
97  |     fn _unpack(&mut self, dst: &Path) -> io::Result<()> {
    |                --------- move occurs because `self` has type `&mut EntryFields<'_>`, which does not implement the `Copy` trait
...
133 |         try!(fs::File::create(dst).and_then(|mut f| {
    |                                             ------- value moved into closure here
134 |             if try!(io::copy(self, &mut f)) != self.size {
    |                              ---- variable moved due to use in closure
...
145 |         if let Ok(mtime) = self.header.mtime() {
    |                            ^^^^^^^^^^^^^^^^^^^ value borrowed here after move

So the borrow checker improvements in 2018-ish haven't fixed the regression here.

tar 0.3.4 is also affected, but latest 0.4.33 is not.

I'm closing this as with current policies this can't be changed.

@rustbot label T-libs-api

@est31 est31 closed this as completed Dec 15, 2022
@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Dec 15, 2022
@m-ou-se m-ou-se reopened this May 1, 2023
@m-ou-se m-ou-se added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label May 1, 2023
@est31
Copy link
Member Author

est31 commented May 6, 2023

For the libs team meeting, see #111063 with crater runs for the suggested change as well as my analysis of the results.

@dtolnay
Copy link
Member

dtolnay commented May 30, 2023

The proposed change breaks reborrows. For example in the following code:

the error is:

because against the current copy signature, the following is a reborrow of buf:

let buf: &mut Vec<u8> = ...;
io::copy(..., buf)?;  // IMPLICIT REBORROW equivalent to `&mut *buf`

// buf remains usable here

whereas in the proposed new copy signature it is a move of buf.

As far as I know, there is no inherent reason it has to be this way. If you have fn old_copy<W: ?Sized + Write>(w: &mut W) and fn new_copy<W: Write>(w: W), then old_copy::<Vec<u8>> and new_copy::<&mut Vec<u8>> have the same signature. Both of them take an argument of type &mut Vec<u8>. One could imagine wanting Rust's reborrow behavior to be identical between these two identical signatures. I don't currently know any reason that it would be a breaking change to perform reborrowing for both.

For now the crater breakages are beyond where I think we can push this change through. But if a future smarter borrow checker is able to do reborrows for an argument of type &mut T even when the formal parameter's type is a generic type, then I would love to reconsider this change at that point.

@rfcbot fcp close

@rfcbot
Copy link

rfcbot commented May 30, 2023

Team member @dtolnay has proposed to close this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. labels May 30, 2023
@Amanieu Amanieu removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Jun 1, 2023
@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Jun 6, 2023
@rfcbot
Copy link

rfcbot commented Jun 6, 2023

🔔 This is now entering its final comment period, as per the review above. 🔔

@dtolnay dtolnay removed the rust-2-breakage-wishlist In the wishlist of breaking changes that requires rust 2.0 label Jun 7, 2023
@dtolnay dtolnay closed this as completed Jun 7, 2023
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Jun 16, 2023
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Jun 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-close This PR / issue is in PFCP or FCP with a disposition to close it. finished-final-comment-period The final comment period is finished for this PR / Issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants