2

I'm trying to implement From for a type I want to get as a mutable reference, so I impl it for a &mut TheType, but then how do I properly call from? Attempts I performed fail because it tries to do reflexion (TheType from TheType) or can't (or don't know how to) call from from a type &mut TheType.

Code will explain it better hopefully:

enum Component {
    Position(Point),
    //other stuff
}

struct Point {
    x: i32,
    y: i32,
}

impl<'a> std::convert::From<&'a mut Component> for &'a mut Point {
    fn from(comp: &'a mut Component) -> &mut Point {
        // If let or match for Components that can contain Points
        if let &mut Component::Position(ref mut point) = comp {
            point
        } else { panic!("Cannot make a Point out of this component!"); }
    }
}

// Some function somewhere where I know for a fact that the component passed can contain a Point. And I need to modify the contained Point. I could do if let or match here, but that would easily bloat my code since there's a few other Components I want to implement similar Froms and several functions like this one. 
fn foo(..., component: &mut Component) {
    // Error: Tries to do a reflexive From, expecting a Point, not a Component
    // Meaning it is trying to make a regular point, and then grab a mutable ref out of it, right?
    let component = &mut Point::from(component)

    // I try to do this, but seems like this is not a thing.
    let component = (&mut Point)::from(component) // Error: unexpected ':'

    ...
}

Is what I'm trying to do here possible? The impl From above compiles just fine, is just the calling of it that escapes me.

GGalizzi
  • 813
  • 1
  • 10
  • 18

2 Answers2

5

One way to do this would be to specify the type of component like this:

let component: &mut Point = From::from(component);

As Simon Whitehead pointed out, the more idiomatic way to do this would be to use the corresponding function into():

let component: &mut Point = component.into();
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Wesley Wiser
  • 9,491
  • 4
  • 50
  • 69
  • 3
    Also, because the stdlib includes many variations of `impl Into for T where U: From` you can also do this after implementing `From`: `let component: &mut Point = component.into();` – Simon Whitehead Feb 09 '17 at 21:22
3

The proper syntax is:

let component = <&mut Point>::from(component);

It's essentially the "turbofish" syntax without the leading ::.

Francis Gagné
  • 60,274
  • 7
  • 180
  • 155