2017-01-07 30 views
9

Chcę utworzyć makro generujące formatera (Display, Debug, ...) dla struktury zawierającej pojedynczy typ ogólny.Problemy z tworzeniem bloku implików przy użyciu makra w Rust

macro_rules! create_formatter { 
    ($type_name:ident<$gen_param:ident>, $trait:path) => { 
     impl<$gen_param: $trait> $trait for $type_name<$gen_param> { 
      fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 
       // isn't yet implemented 
      } 
     } 
    }; 
} 

Kiedy wywołać makro później w kodzie (create_formatter!(MyStruct<T>, std::fmt::Display);), kompilator daje następującą opinię:

error: expected one of `,`, `=`, `>`, or `?`, found `std::fmt::Display` 
--> test.rs:6:26 
| 
6|   impl<$gen_param: $trait> $trait for $type_name<$gen_param> { 
|       ^^^^^^^^ 

Co robię źle?

+1

Działa, jeśli użyjesz 'ident' dla specyfikatora fragmentu używanego do powiązania cechy. (Oznacza to również, że musisz wywołać to za pomocą 'Display' i dodać' use std :: fmt :: Display; '). Ale nie jestem pewien dlaczego. – wimh

Odpowiedz

5

To wydaje się być tajemnicze! Wydaje się, że problem polega na sposobie, w jaki przetwarzany jest wynik makra: ponieważ został częściowo wstępnie przetworzony jako path podczas przetwarzania makra, nie pasuje on już do reguły parsowania dla powiązania cechy. Było o tym bug raised a few weeks ago.

Jest jednak dobra wiadomość - it's been fixed! Przykład faktycznie działa w wersjach beta lub kompilatorach nocnych (playground), ale należy zmienić nazwę na $trait na $t jako trait jest słowem kluczowym.