-2

I'm trying to print a custom type:

struct Node<T> {
    prev: Option<Box<Node<T>>>,
    element: T,
    next: Option<Box<Node<T>>>,
}

Now, the problem:

print!(
    "{0} -> {1}",
    String::from(node.element),
    String::from(node.next)
);
error[E0277]: the trait bound `std::string::String: std::convert::From<T>` is not satisfied
  --> src/lib.rs:10:9
   |
10 |         String::from(node.element),
   |         ^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `std::string::String`
   |
   = help: consider adding a `where std::string::String: std::convert::From<T>` bound
   = note: required by `std::convert::From::from`

error[E0277]: the trait bound `std::string::String: std::convert::From<std::option::Option<std::boxed::Box<Node<T>>>>` is not satisfied
  --> src/lib.rs:11:9
   |
11 |         String::from(node.next)
   |         ^^^^^^^^^^^^ the trait `std::convert::From<std::option::Option<std::boxed::Box<Node<T>>>>` is not implemented for `std::string::String`
   |
   = help: the following implementations were found:
             <std::string::String as std::convert::From<&'a str>>
             <std::string::String as std::convert::From<std::borrow::Cow<'a, str>>>
             <std::string::String as std::convert::From<std::boxed::Box<str>>>
   = note: required by `std::convert::From::from`

How to cast node.element to String and Option<Box<Node<T>>> to String?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Can you explain what you find difficult about the error message? What about the help text suggested in the error message? – Shepmaster Apr 01 '19 at 18:55
  • 1
    That being said, using `From` for outputting things is kinda wasteful - `from` uses the argument by value, so you can't use it afterwards unless it's `Copy`. You want either `Debug` or `Display` (the former is derivable, btw). – Michail Apr 01 '19 at 18:57

1 Answers1

3

As the compiler tells you:

consider adding a where std::string::String: std::convert::From<T> bound

fn example<T>(node: Node<T>)
where
    String: From<T>,
{
    // ...
}

This won't work for String: From<Option<Node<T>>> because there's no such implementation.


If you want to format your struct, you will want to require an implementation of Display instead. There's no reason to convert a value into a String just for the purposes of displaying it:

fn example<T>(node: Node<T>)
where
    T: std::fmt::Display
{
    // ...
}

Again, this doesn't work in your bigger case because neither Node<T> or Option<T> implement Display.

See also:

You might want something like

fn example<T>(mut node: Node<T>)
where
    T: std::fmt::Display,
{
    print!("{}", node.element);
    while let Some(n) = node.next {
        print!(" -> {}", n.element);
        node = *n;
    }
}

or

fn example<T>(mut node: &Node<T>)
where
    T: std::fmt::Display,
{
    print!("{}", node.element);
    while let Some(n) = &node.next {
        print!(" -> {}", n.element);
        node = &n;
    }
}

Or even to implement Display / Debug yourself using the same code.

You should also read Learning Rust With Entirely Too Many Linked Lists. You are attempting to create a doubly-linked list which is not possible in safe Rust.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366