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

Implement always-fallible TryFrom for usize/isize conversions that are infallible on some platforms #51564

Merged
merged 1 commit into from
Jul 3, 2018

Conversation

SimonSapin
Copy link
Contributor

@SimonSapin SimonSapin commented Jun 14, 2018

This reverts commit 837d6c7 "Remove TryFrom impls that might become conditionally-infallible with a portability lint".

This fixes #49415 by adding (restoring) missing TryFrom impls for integer conversions to or from usize or isize, by making them always fallible at the type system level (that is, with Error=TryFromIntError) even though they happen to be infallible on some platforms (for some values of size_of::<usize>()).

They had been removed to allow the possibility to conditionally having some of them be infallible From impls instead, depending on the platforms, and have the portability lint warn when they are used in code that is not already opting into non-portability. For example #[allow(some_lint)] usize::from(x: u64) would be valid on code that only targets 64-bit platforms.

This PR gives up on this possiblity for two reasons:

  • Based on discussion with @aturon, it seems that the portability lint is not happening any time soon. It’s better to have the conversions be available at all than keep blocking them for so long. Portability-lint-gated platform-specific APIs can always be added separately later.

  • For code that is fine with fallibility, the alternative would force it to opt into "non-portability" even though there would be no real portability issue.

@SimonSapin SimonSapin added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jun 14, 2018
@rust-highfive
Copy link
Collaborator

r? @withoutboats

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 14, 2018
@SimonSapin
Copy link
Contributor Author

@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Jun 14, 2018

Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once a majority of reviewers approve (and none object), 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-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jun 14, 2018
@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-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jun 14, 2018
@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-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jun 14, 2018
@ollie27
Copy link
Member

ollie27 commented Jun 16, 2018

So if a trait impl can't be implemented for all targets it shouldn't be implemented for any even with a portability lint? Is that going to be the new policy or is there something special about From and/or isize/usize?

The way I see it is that having different error types for impls like impl TryFrom<isize> for i32 is just a consequence of isize and usize being different sizes on different targets. It's no different to the differing error types for impl TryFrom<c_long> for i32 which apparently isn't an issue. It's already easy to write non-portable code involving usize or isize so differing associated types on impls for them isn't a new issue. For example the following code compiles (with no warnings) and runs on 64 bit platforms but fails on 32 bit:

fn main() {
    assert_eq!(4294967296usize, 1usize << 32);
}

isize and usize aren't portable types.

@SimonSapin
Copy link
Contributor Author

So if a trait impl can't be implemented for all targets it shouldn't be implemented for any even with a portability lint?

This presumes the existence of a portability lint, which most likely won’t be the case for many months yet.

By the way this is why non-pointer-sized Atomic* types are not stable yet.

@ltratt
Copy link
Contributor

ltratt commented Jun 20, 2018

Thanks for this @SimonSapin -- I know quite a few of us will be grateful for this one being merged!

@SimonSapin SimonSapin changed the title Revert "Remove TryFrom impls that might become conditionally-infallible with a portability lint" Implement always-fallible TryFrom for usize/isize conversions that are infallible on some platforms Jun 23, 2018
@rfcbot
Copy link

rfcbot commented Jul 1, 2018

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

@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 Jul 1, 2018
@Kimundi
Copy link
Member

Kimundi commented Jul 1, 2018

While I agree with @ollie27 that isize and usize are non-portable types, and as such having different trait impls for them for them would not be unexpected, I also think that just providing them with a unified error type wouldn't be a problem, and actually make the conversions somewhat more portable (because the code compiles the same on any platform).

Performance-wise it also shouldn't make much of a difference, since presumably the optimizer will be able to figure out that a Err value will never be produced by the conversion.

@SimonSapin
Copy link
Contributor Author

Indeed, those conversions are marked #[inline] and the optimizer does eliminate .unwrap() when it never panics:
http://play.rust-lang.org/?gist=3167bddf125915403b64eb98fcf16fe5&version=stable&mode=release&edition=2015

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Jul 2, 2018

📌 Commit e7c122c has been approved by alexcrichton

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 2, 2018
@ollie27
Copy link
Member

ollie27 commented Jul 2, 2018

This issue was never about performance. I don't know why people keep mentioning that. This issue is about whether the From impls proposed in #37423 can be added in the future. It was my understanding that the portability lint was accepted to allow such impls but this PR will make adding them a breaking change. Using ! as the error type for the infallible conversions will allow those impls to be added without breakage.

The question now is, if those impls won't be allowed, will the portability lint be usable for any trait impls?

@SimonSapin
Copy link
Contributor Author

Right, this isn’t about performance, I was only responding that it isn’t a concern.

This issue is about whether the From impls proposed in #37423 can be added in the future.

Right, and this PR is proposing that they can not because we’re adding different, overlapping impls.

Using ! as the error type for the infallible conversions will allow those impls to be added without breakage.

This proposal is almost the same as adding From impls: public APIs (in this case associated types and return types) vary by platform, so code that compiles for a target of a given pointer size might have a type error for a different target.

Which I think we should’t do without a portability lint. And even then, as mentioned in this PR’s description marking some TryFrom integer conversions as non-portable is a downside, for callers that don’t care about the error type or whether it is uninhabited.

The question now is, if those impls won't be allowed, will the portability lint be usable for any trait impls?

That is a question that is unresolved as far as I know: will the lint be powerful enough to detect portability issues in enough cases. (For example: using a blanket portable impl which depends on a non-portable impl.)

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jul 2, 2018
Implement always-fallible TryFrom for usize/isize conversions that are infallible on some platforms

This reverts commit 837d6c7 "Remove TryFrom impls that might become conditionally-infallible with a portability lint".

This fixes rust-lang#49415 by adding (restoring) missing `TryFrom` impls for integer conversions to or from `usize` or `isize`, by making them always fallible at the type system level (that is, with `Error=TryFromIntError`) even though they happen to be infallible on some platforms (for some values of `size_of::<usize>()`).

They had been removed to allow the possibility to conditionally having some of them be infallible `From` impls instead, depending on the platforms, and have the [portability lint](rust-lang/rfcs#1868) warn when they are used in code that is not already opting into non-portability. For example `#[allow(some_lint)] usize::from(x: u64)` would be valid on code that only targets 64-bit platforms.

This PR gives up on this possiblity for two reasons:

* Based on discussion with @aturon, it seems that the portability lint is not happening any time soon. It’s better to have the conversions be available *at all* than keep blocking them for so long. Portability-lint-gated platform-specific APIs can always be added separately later.

* For code that is fine with fallibility, the alternative would force it to opt into "non-portability" even though there would be no real portability issue.
@bors
Copy link
Contributor

bors commented Jul 3, 2018

⌛ Testing commit e7c122c with merge 0fb6e39...

bors added a commit that referenced this pull request Jul 3, 2018
Implement always-fallible TryFrom for usize/isize conversions that are infallible on some platforms

This reverts commit 837d6c7 "Remove TryFrom impls that might become conditionally-infallible with a portability lint".

This fixes #49415 by adding (restoring) missing `TryFrom` impls for integer conversions to or from `usize` or `isize`, by making them always fallible at the type system level (that is, with `Error=TryFromIntError`) even though they happen to be infallible on some platforms (for some values of `size_of::<usize>()`).

They had been removed to allow the possibility to conditionally having some of them be infallible `From` impls instead, depending on the platforms, and have the [portability lint](rust-lang/rfcs#1868) warn when they are used in code that is not already opting into non-portability. For example `#[allow(some_lint)] usize::from(x: u64)` would be valid on code that only targets 64-bit platforms.

This PR gives up on this possiblity for two reasons:

* Based on discussion with @aturon, it seems that the portability lint is not happening any time soon. It’s better to have the conversions be available *at all* than keep blocking them for so long. Portability-lint-gated platform-specific APIs can always be added separately later.

* For code that is fine with fallibility, the alternative would force it to opt into "non-portability" even though there would be no real portability issue.
@bors
Copy link
Contributor

bors commented Jul 3, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing 0fb6e39 to master...

@bors bors merged commit e7c122c into rust-lang:master Jul 3, 2018
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Jul 11, 2018
@SimonSapin SimonSapin deleted the try-int branch July 13, 2018 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking issue for platform-dependent-API TryFrom impls involving usize/isize
9 participants