Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I alias fully qualified syntax?

I have some code where I have many instances of fully qualified syntax; as an example:

mod hal {
    pub trait Backend {
        type Device;
    }
}

mod back {
    pub struct Backend {}

    impl ::hal::Backend for Backend {
        type Device = i32;
    }
}

fn main() {
    let d: back::Backend::Device = 0;
}

playground

In order to avoid errors like:

error[E0223]: ambiguous associated type
  --> src/main.rs:16:12
   |
16 |     let d: back::Backend::Device = 0;
   |            ^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
   |
   = note: specify the type using the syntax `<back::Backend as Trait>::Device`

Is there a nice way in which I can alias SomeType as SomeTrait? Then, wherever this instance of fully qualified syntax is needed, I can write:

<S>::associated_fn(...)

Note that this error does not occur because there are actually multiple implementations of some trait's definition (which is what FQS is supposed to handle, according to The Rust Programming Language).

like image 371
bzm3r Avatar asked Oct 05 '18 00:10

bzm3r


2 Answers

In your example, you can rename some of the parts so you can refer to them without conflicts in the shortened form:

use hal::Backend;
use back::Backend as BackendImpl;

fn main() {
    let d: <BackendImpl as Backend>::Device = 0;
}

You may also consider defining a type alias, which is less ambiguous to access:

mod hal {
    pub trait Backend {
        type Device;
    }
}

mod back {
    pub struct Backend {}
    pub type Device = i32;
    impl ::hal::Backend for Backend {
        type Device = Device;
    }
}

fn main() {
    let d: back::Device = 0;
}
like image 195
Peter Hall Avatar answered Oct 10 '22 10:10

Peter Hall


No, there is no way to alias the fully-qualified syntax. Doing so doesn't make sense to me as the whole point of this syntax is to be completely unambiguous.


All of this assumes that you actually need fully-qualified syntax. As the name indicates, there's usually shorter ways of writing the code. These are all equivalent if no other traits defining to_string are in scope and the type itself doesn't implement a method of the same name:

<i32 as ToString>::to_string(&42);
ToString::to_string(&42);
i32::to_string(&42);
42.to_string();

See also:

  • How to call a method when a trait and struct use the same name?
  • How do I disambiguate traits in Rust?
like image 40
Shepmaster Avatar answered Oct 10 '22 10:10

Shepmaster