papplesharp
papplesharp

Reputation: 292

How to pass reference of Into to another function?

I have a function that accepts a type Into<A>, how do you call into it, assuming I have a Vec of Into<A>?

Here is some sample code which fails to compile:

struct A {}

struct B {}

impl From<B> for A {
    fn from(value: B) -> A {
        A {}
    }
}

impl From<&B> for A {
    fn from(value: &B) -> A {
        A {}
    }
}

fn do_once<H: Into<A>>(item: H) {
    println!("do_once");
}

fn do_many<J: Into<A>>(items: Vec<J>) {
    let item = &items[0];
    do_once(item);
    
    // In the real code, we iterate here over all items.
}

Error:

error[E0277]: the trait bound `A: From<&J>` is not satisfied
  --> src\main.rs:28:5
   |
22 | fn do_once<H: Into<A>>(item: H) {
   |               ------- required by this bound in `do_once`
...
28 |     do_once(item);
   |     ^^^^^^^ the trait `From<&J>` is not implemented for `A`
   |
   = note: required because of the requirements on the impl of `Into<A>` for `&J`

I think the problem is that I am passing an &Into<A>, not an Into<A>.

Is there any solution other than changing do_once to accept &H instead of H? In my real world case, I would like to avoid changing that API.

Upvotes: 0

Views: 87

Answers (1)

Aplet123
Aplet123

Reputation: 35512

Yes, just move the trait bound so &J is Into<A> instead of J:

fn do_many<J>(items: Vec<J>)
where
    for<'a> &'a J: Into<A>
{
    let item = &items[0];
    do_once(item);
    
    // In the real code, we iterate here over all items.
}

Playground link

Upvotes: 1

Related Questions