2016-06-02 6 views
5

Ich möchte, dass mein Prozedurmakro einige BinaryOps durch Methoden ersetzt. Wie stelle ich die Spannen so ein, dass meine Benutzer bei Fehlern nicht völlig verwirrt sind?Wie behandelt man Spannen in prozeduralen Makros richtig?

+0

Können Sie ein Beispiel geben? Sie möchten, dass der Bereich nur die BinaryOp oder den gesamten binären Ausdruck hervorhebt? – kennytm

+0

Jeder Expr benötigt eine Spanne. Wir haben das Original 'BinaryOp'' Expr', den Operator 'Expr' (die unverändert sind, so behalten sie ihre' Span's), das neu erstellte 'MethodCall'' Expr' mit 'Span's für beide 'Expr' und die' Ident' der Methode. Es sind die letzten beiden Span's, an denen ich interessiert bin. – llogiq

Antwort

1

Nach einigem Blick in rustc 's Quelle kam ich zu dem Schluss, dass nach dem "Expansion" -Modell die besten Ergebnisse erzielt. So behalten wir das Original Span aber für die expn_id, die wir erhalten können, indem wir ExtCtxt::backtrace() anrufen.

Es scheint eine gute Idee zu sein, dies in beiden in der Frage beschriebenen Fällen zu setzen. Der -Operator kann als in den (Funktionsaufruf-) Pfad expandiert betrachtet werden, und die ursprüngliche binäre Operation Ausdruck als in den Funktionsaufruf erweitert. In Code:

match expr.unwrap() { 
    .. 
    Expr { node: ExprKind::Binary(Spanned { node: Add, span: op }, l, r), span, .. } => { 
     let bt = self.cx.backtrace(); // get the expansion ID 
     let path = self.cx.path(Span { expn_id: bt, ..op }, vec![crate_name, trait_name, fn_name]); 
     let epath = self.cx.expr_path(path); // path expression 
     let args_expanded = self.fold_exprs(args); 
     self.cx.expr_call(Span { expn_id: bt, ..span }, epath, args_expanded) 
     //^outer expression 
    } 
    .. 
} 
Verwandte Themen