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

IntoStaticStr but from immutable reference to an enum From<&MyEnum> #291

Open
bitcoin-eagle opened this issue Aug 16, 2023 · 7 comments
Open

Comments

@bitcoin-eagle
Copy link

I need IntoStaticStr but from immutable reference to an enum From<&MyEnum> for &'static str on an &Enum is it possible to add?

Because without it the only way is to clone the enum to get the static string by using .into()
.as_ref() doesn't work either because it doesn't return the 'static lifetime

Or am I just missing some rust construct that can easily achieve this?

use strum_macros::{AsRefStr, IntoStaticStr};

#[derive(AsRefStr, IntoStaticStr)]
enum MyEnum {
    Foo,
}
fn main() {
    let v = MyEnum::Foo;
    let str2: &'static str = v.as_ref();
    let str: &'static str = v.into();
    drop(v);
}
error[E0597]: `v` does not live long enough
  --> src/main.rs:9:30
   |
8  |     let v = MyEnum::Foo;
   |         - binding `v` declared here
9  |     let str2: &'static str = v.as_ref();
   |               ------------   ^^^^^^^^^^ borrowed value does not live long enough
   |               |
   |               type annotation requires that `v` is borrowed for `'static`
...
12 | }
   | - `v` dropped here while still borrowed

error[E0505]: cannot move out of `v` because it is borrowed
  --> src/main.rs:10:29
   |
8  |     let v = MyEnum::Foo;
   |         - binding `v` declared here
9  |     let str2: &'static str = v.as_ref();
   |               ------------   ---------- borrow of `v` occurs here
   |               |
   |               type annotation requires that `v` is borrowed for `'static`
10 |     let str: &'static str = v.into();
   |                             ^ move out of `v` occurs here

error[E0505]: cannot move out of `v` because it is borrowed
  --> src/main.rs:11:10
   |
8  |     let v = MyEnum::Foo;
   |         - binding `v` declared here
9  |     let str2: &'static str = v.as_ref();
   |               ------------   ---------- borrow of `v` occurs here
   |               |
   |               type annotation requires that `v` is borrowed for `'static`
10 |     let str: &'static str = v.into();
11 |     drop(v);
   |          ^ move out of `v` occurs here

error[E0382]: use of moved value: `v`
   --> src/main.rs:11:10
    |
8   |     let v = MyEnum::Foo;
    |         - move occurs because `v` has type `MyEnum`, which does not implement the `Copy` trait
9   |     let str2: &'static str = v.as_ref();
10  |     let str: &'static str = v.into();
    |                               ------ `v` moved due to this method call
11  |     drop(v);
    |          ^ value used here after move
    |
note: `into` takes ownership of the receiver `self`, which moves `v`
   --> /home/lajos/snap/rustup/common/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:448:13
    |
448 |     fn into(self) -> T;
    |             ^^^^

Some errors have detailed explanations: E0382, E0505, E0597.
For more information about an error, try `rustc --explain E0382`.
@bitcoin-eagle
Copy link
Author

#131 AsStr would solve it #131 (comment)

@bitcoin-eagle
Copy link
Author

maybe also duplicate of #152 ?

@bitcoin-eagle
Copy link
Author

Aww, it actually works with the depracated feature. Can you undeprecate it? or maybe just rename to as_str as suggested in #131 (comment) ?

use strum::{AsStaticRef, AsStaticStr};

#[derive(AsStaticStr)]
enum MyEnum {
    Foo,
}
fn main() {
    let v = MyEnum::Foo;
    let str3: &'static str = v.as_static();
    println!("{}", str3);
    drop(v);
}

@bitcoin-eagle
Copy link
Author

bitcoin-eagle commented Aug 16, 2023

How about AsStaticRef<str> -> AsStr and AsStaticStr -> AsStr

pub trait AsStr{
    fn as_str(&self) -> &'static str
}

Plus also if the From<&MyEnum> is possible for IntoStaticStr

@Peternator7
Copy link
Owner

This should already work, but you might need to play with the de-refs to get rustc to pick the right impl. Check out this test for an example

@bitcoin-eagle
Copy link
Author

bitcoin-eagle commented Sep 17, 2023

you are correct, it works.

So I turn this into a question. I don't know how to declare Into<&'static str> trait so it works for both Enum and &Enum. Whereas with AsStaticStr it works. Here is the code I want to make work.

What trait should be added to EnumIntoStaticStr so it compiles?

use strum::{AsStaticRef, AsStaticStr, IntoStaticStr};

trait EnumIntoStaticStr: Into<&'static str> {}
impl<T: Into<&'static str>> EnumIntoStaticStr for T {}
trait EnumAsStaticStr: AsStaticRef<str> {}
impl<T: AsStaticRef<str>> EnumAsStaticStr for T {}

#[derive(AsStaticStr)]
enum MyEnum {
    Foo,
    Bar(String),
}

#[derive(IntoStaticStr)]
enum MyEnum2 {
    Foo2,
    Bar(String),
}

fn main() {
    let v = MyEnum::Foo;
    let str = borrow_as_str(&v);
    drop(v);
    println!("{}", str);

    let v2 = MyEnum2::Foo2;
    let str2 = borrow_into_str(&v2);
    drop(v2);
    println!("{}", str2);
}

fn move_as_str(v: impl EnumAsStaticStr) -> &'static str {
    v.as_static()
}

fn borrow_as_str(v: &impl EnumAsStaticStr) -> &'static str {
    v.as_static()
}

fn move_into_str(v: impl EnumIntoStaticStr) -> &'static str {
    v.into()
}

fn borrow_into_str(v: &impl EnumIntoStaticStr) -> &'static str {
    v.into()
}

Error:

error[E0277]: the trait bound `&str: From<&impl EnumIntoStaticStr>` is not satisfied
  --> src/main.rs:45:7
   |
45 |     v.into()
   |       ^^^^ the trait `From<&impl EnumIntoStaticStr>` is not implemented for `&str`
   |
   = note: required for `&impl EnumIntoStaticStr` to implement `Into<&str>`
help: consider dereferencing here
   |
45 |     (*v).into()
   |     ++ +

For more information about this error, try `rustc --explain E0277`.```

@bitcoin-eagle
Copy link
Author

I got my answer on stackoverflow https://stackoverflow.com/questions/77120723/how-to-declare-supertraits-intot-so-it-works-with-both-move-and-borrow/77122298#77122298

I would vouch for keeping AsStaticStr because there is a difference from IntoStaticStr as shown in previous comment.

Apart from that this issue can be closed from my side

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

2 participants