6

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).

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
bzm3r
  • 3,113
  • 6
  • 34
  • 67
  • Why do you have "many instances of fully qualified syntax" to start with? – Shepmaster Oct 05 '18 at 01:30
  • @Shepmaster I am using a library called `gfx-rs`, which has something called `hal` (hardware abstraction layer). `hal` is really a bunch of traits, and these traits are implemented by platform specific backends (e.g. vulkan, directx, etc.). Thus, I often have to write `::some_fn`, in order to get to the implementation of some particular function. – bzm3r Oct 05 '18 at 01:36
  • None of that indicates why you have to use FQS instead of just calling the methods directly. Are there multiple traits defining `some_fn`? – Shepmaster Oct 05 '18 at 01:39
  • @Shepmaster This is something I do not quite understand about the library, because it seems to me that `hal` does not implement multiple traits defining some associated function, or type...however, the compiler complains about receiving an ambiguous type when FQS is left out. I have included an example of the error in the question now. – bzm3r Oct 05 '18 at 02:18
  • @Shepmaster so i was able to confirm that the error occurs not because there are multiple impls of some definition; here is a minimal example that reproduces the same error (courtesy of someone on the project's gitter): https://play.rust-lang.org/?gist=710159b24866cf75bff623947e57bbb4&version=stable&mode=debug&edition=2015 – bzm3r Oct 05 '18 at 03:29

2 Answers2

4

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;
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
3

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:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • so in OP's example you could just write `gfx_vulkan::backend::Backend::some_fn();` ? – Rots Oct 05 '18 at 02:08
  • @Rots no, it doesn't seem like you can, i have added a MnWE to the question now – bzm3r Oct 05 '18 at 03:34
  • That [works with functions](https://play.rust-lang.org/?gist=791a7c33e12203a3a17d18e2994db217&version=stable&mode=debug&edition=2015) but apparently not with associated types. – Jmb Oct 05 '18 at 06:41