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

[Design] confusing target_pointer_width = "64" usize convertion design #138218

Open
loynoir opened this issue Mar 8, 2025 · 3 comments
Open

[Design] confusing target_pointer_width = "64" usize convertion design #138218

loynoir opened this issue Mar 8, 2025 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@loynoir
Copy link

loynoir commented Mar 8, 2025

Title

confusing target_pointer_width = "64" usize convertion design

Actual

        #[cfg(target_pointer_width = "64")]
        {
            let _ = usize::try_from(42u64).unwrap();
            let _ = usize::try_from(42u32).unwrap();
            let _ = usize::from(42u16);
        }

Expected

When under target_pointer_width 64, should always success, and try is not necessary.

        #[cfg(CONDITION)]
        {
            let _ = usize::from(42u64);
            let _ = usize::from(42u32);
            let _ = usize::from(42u16);
        }

Related

https://github.com/rust-lang/rust/blob/master/library/core/src/convert/num.rs

@loynoir loynoir added the C-bug Category: This is a bug. label Mar 8, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 8, 2025
@loynoir loynoir changed the title confusing target_pointer_width = "64" usize convertion [Design] confusing target_pointer_width = "64" usize convertion Mar 8, 2025
@loynoir loynoir changed the title [Design] confusing target_pointer_width = "64" usize convertion [Design] confusing target_pointer_width = "64" usize convertion design Mar 8, 2025
@Noratrieb
Copy link
Member

This is deliberate, we don't want people writing unportable code by accident. This is why trait implementations are not made available conditionally.

@Noratrieb Noratrieb added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 8, 2025
@loynoir
Copy link
Author

loynoir commented Mar 8, 2025

This is deliberate, we don't want people writing unportable code by accident.

Why is unportable?

Are there real world target_pointer_width = "64" hardware, which usize fail from u32 and u64, but ok from u16?

        #[cfg(target_pointer_width = "64")]
        {
            // let _ = usize::try_from(42u64).unwrap();
            // let _ = usize::try_from(42u32).unwrap();
            // let _ = usize::from(42u16);

            let _ = usize::from(42u64);
            let _ = usize::from(42u32);
            let _ = usize::from(42u16);
        }

@GKFX
Copy link
Contributor

GKFX commented Mar 9, 2025

@loynoir If there was an implementation of From<u64> for usize on 64-bit targets but not on 32-bit targets, then users targetting 64-bit machines could compile let x: usize = 42u64.into(). There would be no requirement for the user to write that within #[cfg(target_pointer_width = "64")] and no visible indication that this code only built for 64-bit, particularly if the From trait is being used in a more complex way. Then, when they tried to use a 32-bit target, the code would unexpectedly fail to compile. This situation where From implementations disappear when changing platforms is the portability problem.

That said, I've never fully agreed with Rust's choice here - if like most users you never expect to target 16-bit, then you end up writing try_from().unwrap() which is both verbose and has the potential to panic. Or you use as usize, which has the potential to silently give the wrong result.

A possible middle ground would be to have usize::from_u16, usize::from_u32, usize::from_u64 and usize::to_uXX etc. defined only on platforms where that is lossless, which is a less subtle compatibility issue than conditionally defining the From trait.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. 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

4 participants