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

Added lossless From/Into conversions for usize and isize as appropriate #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kevinaboos
Copy link

I needed easier conversions from usize/isize types, so I added them here as appropriate, based on the bitwidth of usize/isize.

Let me know if you would like any changes. All tests pass for 32-bit and 64-bit targets (tested on Linux). I don't have a 16-bit target, but things should work for that as well.

@kevinaboos
Copy link
Author

Hi @kjetilkjeka , any possibility of merging this PR? Let me know if you have any qualms or concerns.

@awygle
Copy link

awygle commented Jun 26, 2019

Just another request to please merge this.

@kjetilkjeka
Copy link
Collaborator

Thanks a lot for the PR and I'm sorry it took me so long to respond.

Looking at the rust std lib it seems like the precedence is to implement TryFrom for these kinds of conversions instead of conditionally compiled From conversion. Converting is then done with try_from().unwrap() or try_into().unwrap() which would never fail for some platforms. Would implementing this as fallible conversions (TryFrom) to conform as close to the std lib as possible be helpful for your use cases?

Infallible conversions from (u|i)(1-15)to usize and isize can be implemented regardless without any conditional compilation.

@kevinaboos
Copy link
Author

Hmm, we could do that I suppose, but wouldn't conditional compilation be better? That way you get compiler errors instead of a panic at runtime.

Could you point me to where in the std library the conversions are performed in that manner?

@kjetilkjeka
Copy link
Collaborator

Hmm, we could do that I suppose, but wouldn't conditional compilation be better? That way you get compiler errors instead of a panic at runtime.

I think both have advantages. Failing in compile time rather than run time is nice. On the other hand, compile-time configs will make it harder to write libraries that work well for all sorts of architectures. When using TryFrom the library author will be able to handle the error case in. When instead using From the library will fail to compile on some architectures.

When writing binaries for a specific target I would argue that they're somewhat equivalent when used correctly. A TryFrom conversion for u32 to usize will in practice never panic on 32/64 bit archs.

I would also argue with the principle of least astonishment that u31 and u33 should behave as similar as possible to u32.

Could you point me to where in the std library the conversions are performed in that manner?

Look at the implementations for usize and search for TryFrom and From to see which trait implementations that exists.

@kevinaboos
Copy link
Author

Thanks for the links. I'm definitely down with the principle of least surprise, and in my opinion, compile-time errors are precisely that.

When writing binaries for a specific target I would argue that they're somewhat equivalent when used correctly. A TryFrom conversion for u32 to usize will in practice never panic on 32/64 bit archs.

If it won't panic in practice, then why not push that guarantee to compile time? That's in line with Rust's existing goals.

Respectfully, I don't quite see how compile-time conditional builds make it harder to write libraries that work well for multiple architectures. The conditional compilation flags are based on target pointer width only, which every platform will clearly define, and it won't ever change for a given library.

Anywho, I must admit that my choice to use conditional compilation is also motivated by the environment in which I'm using this crate: an OS kernel that forbids all panicking code; thus, something like try_into().unwrap() would be disallowed.

Is there any way to have both options? Obviously, your crate, your call. Perhaps we could do a TryFrom/TryInto implementation that is implemented unconditionally for all *size types, alongside the target_pointer_width-gated changes I've proposed here?

@awygle
Copy link

awygle commented Jul 2, 2019

I don't have a particular horse in this race, but I would say I also have a weak preference for the compile-time checking, or for providing both options (perhaps behind a feature?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants