Как можно реплицировать шаблон SFINAE на основе шаблонов C ++ в Rust? - PullRequest
0 голосов
/ 10 июня 2018

У меня есть следующее:

trait Runnable {
    fn run(&self);
}

struct Foo<T> {
    // Something
}

impl<T> Runnable for Foo<T>
where
    T: Send + Sync,
{
    fn run(&self) {}
}

impl<T> Runnable for Foo<T>
where
    T: Send + ?Sync,
{
    fn run(&self) {}
}

Компилятор жалуется на дубликат impl, хотя T является взаимоисключающим в обоих случаях:

error[E0119]: conflicting implementations of trait `Runnable` for type `Foo<_>`:
  --> src/main.rs:16:1
   |
9  | / impl<T> Runnable for Foo<T>
10 | | where
11 | |     T: Send + Sync,
12 | | {
13 | |     fn run(&self) {}
14 | | }
   | |_- first implementation here
15 | 
16 | / impl<T> Runnable for Foo<T>
17 | | where
18 | |     T: Send + ?Sync,
19 | | {
20 | |     fn run(&self) {}
21 | | }
   | |_^ conflicting implementation for `Foo<_>`

1 Ответ

0 голосов
/ 10 июня 2018

Требуется специализация:

#![feature(specialization)]

trait Runnable {
    fn run(&self);
}

struct Foo<T> {
    _t: T,
}

impl<T> Runnable for Foo<T>
where
    T: Send + Sync,
{
    fn run(&self) {}
}

impl<T> Runnable for Foo<T>
where
    T: Send,
{
    default fn run(&self) {}
//  ^^^^^^^ this is the magic you need
}

fn main() {}

Однако, начиная с Rust 1.26.2, специализация нестабильна и требует ночного компилятора.

...