Using generic trait methods like .into() when type inference is impossible

I don't think there is a better way. Since the type parameter is on the trait, not the method into(), the turbofish operator into::<i32>() doesn't work. As you said, you can make it work by using the fully-qualified-syntax:

Into::<i32>::into(a)

Note, that Into is reexported in std::prelude, which means that you never have to specify the full path, as the trait is always in scope.

Of course, there is also always the possibility to bind your temporary to a name and use the type annotation of the let-binding:

let tmp: i32 = a.into();

It might be better in the future, though! There is an Type Ascription for Expressions RFC, which was already accepted and implemented. The feature is still unstable, but if it's implemented you could write something like:

println!("{}", (a.into(): i32));   // still unstable :/

You could use From::from:

use std::convert::*;

struct NewType(pub i32);

impl From<NewType> for i32 {
    fn from(src: NewType) -> i32 {
        src.0
    }
}

fn main() {
    let a = NewType(5);
    println!("{}", i32::from(a));
}

You can read more about it in the docs for the convert module.


Apparently, this is possible on Rust nightly with type ascription, which seems to be a feature designed for this use case (playground):

#![feature(type_ascription)]

use std::convert::*;

struct NewType(pub i32);

impl From<NewType> for i32 {
    fn from(src: NewType) -> i32 {
        src.0
    }
}

fn main() {
    let a = NewType(5);
    println!("{}", a.into(): i32);
}

Since this is available in an experimental feature, it might be reasonable to conclude that it is otherwise missing from the language proper.