From trait discoverability

Hi Friends,

I'm fairly new to Rust and am having the following issue. The codebase I work in liberally uses the From<Thing> for OtherThing trait. Invocations of this trait look like some_thing.into(). My problem is that its difficult to tell where this is called. For example, lets say I have the following definition:

struct Person {
  first_name: String,
  last_name: String
}

impl From<MyStruct> for String {
  fn from(m: MyStruct) -> String {
    format!("{},{}", m.first_name, m.last_name)
  }
}

pub fn do_thing(s: String) {
  println!("S is: {}", s);
}


pub fn main() {
  let p = Person{
    first_name: String::from("dave"), 
    last_name: String::from("someone")
  };
  do_thing(p.into());
}

Trying to find invocations of this trait via calls to into is difficult. I have to find all variables of type MyStruct, that are being implicitly cast to String. Is there a better way to do this? If not is there a better way to invoke this trait to make it easier to search?

Thank you!

If you comment out the From implementation then run cargo check --message-format short, the compiler will tell you all the locations it was used.

Edit: cheeky playground demo:

Hi Emy,

Thanks for the response! Commenting out the trait and finding what doesn't compile is brilliant! I was hoping that rust analyzer would provide a lookup without having to edit code, but I'll take it.

1 Like

Ah, this is like the problem in Java of trying to find (for example) uses of toString specific to the type (Java class) of interest, and instead the IDE returns every reference to every call of toString across the entire project no matter which type the calling object belongs to.

Same thing (using rust-analyzer via the LSP in Helix at least) when trying to find references to into and getting back every call to into no matter what the types involved (including everything within the code of the Rust std library).

I reckon emy is right that forcing a compiler error is the easiest way, but it's frustrating that the compiler can deduce the type-specific calls while rust-analyzer seemingly cannot.

1 Like

As an aside, you might be looking for the Display in std::fmt - Rust trait instead. That's the one used by {} in format strings, and if you implement it you also automatically get a .to_string().

Not that it really solves your problem, since it just moves it to finding uses of Display, but I find that Froms are best when they're really uninteresting, and thus you don't really think about them ever.

2 Likes

Nitpick: Conversions in Rust using the From/Into traits are neither implicit nor type castings. The calls are explicit (Type::from or variable.into), and you require these trait implementations to exist for this to work; that is, you can't fool the compiler with a type cast.