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

Deprecate the FromPrimitive trait #16920

Closed
aochagavia opened this issue Sep 1, 2014 · 7 comments
Closed

Deprecate the FromPrimitive trait #16920

aochagavia opened this issue Sep 1, 2014 · 7 comments

Comments

@aochagavia
Copy link
Contributor

Two reasons:

  • Different types need to deal with this differently (see examples below). Having only one way to do it causes confusion, because it forces you to return an Option, even when the function cannot return None. The standard library is full of calls followed by unwrap.
  • It is not useful to provide a generic way to do it (please correct me if I am wrong).

Examples:

  • No function of FromPrimitive can ever return None for BigInt
  • Only the functions which accept negative numbers can return None for BigUint
  • For the primitive types, each one has different constraints. For example, FromPrimitive::<i8>::from_i32 can return None because of overflow, while FromPrimitive::<f64>::from_i32 cannot.

The only problem I see is in libtest/stats.rs, where FromPrimitive is used generically. I think however that we can figure it out.

I think the best solution would be have different implementations for each type.

cc @aturon

@huonw
Copy link
Member

huonw commented Sep 1, 2014

This is also used for converting from primitives to enums via deriving. I think it would be weird for this to be a freestanding non-trait impl created by deriving.

@toh-ableton
Copy link

I have unsafe code that uses FromPrimitive to convert an i16 to a custom enum. I've updated to the latest nightly, and I'm now getting a warning that the FromPrimitive "trait is likely to be removed".

What's the idiomatic way to do this conversion? Write a giant match for every enum I need in my code?

@r-darwish
Copy link

Same question as @toh-ableton - What's the new recommended way for converting an integer to a C style enum?

@andersk
Copy link
Contributor

andersk commented Apr 7, 2015

Since nobody else seems to have a good workaround, I just published the enum_primitive crate, which exports an enum_from_primitive! macro that works like #[derive(FromPrimitive)] but for num::FromPrimitive:

#[macro_use] extern crate enum_primitive;
extern crate num;
use num::FromPrimitive;

enum_from_primitive! {
#[derive(Debug, PartialEq)]
enum FooBar {
    Foo = 17,
    Bar = 42,
}
}

fn main() {
    assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
    assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
    assert_eq!(FooBar::from_i32(91), None);
}

@aturon
Copy link
Member

aturon commented Apr 7, 2015

@andersk Wow, thanks so much for doing that! We had been looking into an alternative derive mode that didn't require the traits as a stop-gap, but this is a better way to go for now.

Ultimately, I think we want a more first-class way to handle these conversions and talk about enum size, etc, but that will take some time.

@steveklabnik
Copy link
Member

/cc @rust-lang/libs

@alexcrichton
Copy link
Member

This was actually removed (yay!), so closing.

lnicola pushed a commit to lnicola/rust that referenced this issue Apr 7, 2024
internal: Fix new nightly clippy lints
lnicola pushed a commit to lnicola/rust that referenced this issue Apr 20, 2024
internal: Fix new nightly clippy lints
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

No branches or pull requests

8 participants