Chcę, aby moje makro proceduralne zastąpiło niektóre BinaryOps metodami. Jak ustawić przęsła, aby w przypadku wystąpienia błędów moi użytkownicy nie byli całkowicie zdezorientowani?Jak poprawnie radzić sobie z rozpiętościami w makrach proceduralnych?
5
A
Odpowiedz
1
Po zapoznaniu się ze źródłem doszedłem do wniosku, że po modelu "ekspansji" daje najlepsze rezultaty. Tak więc zachowujemy oryginalny Span
, ale dla expn_id
, który możemy uzyskać dzwoniąc pod numer ExtCtxt::backtrace()
.
Wydaje się, że dobrym pomysłem jest ustawienie tego w obu przypadkach opisanych w pytaniu. Operator może być postrzegany jako rozwinięty w ścieżkę (wywołanie funkcji), a oryginalny wyrażenie binarne jako rozszerzony do wywołania funkcji. W kodzie:
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
}
..
}
Czy możesz podać przykład? Chcesz, aby zakres podświetlał tylko BinaryOp lub całe wyrażenie binarne? – kennytm
Każdy Expr potrzebuje rozpiętości. Mamy oryginalne 'BinaryOp'' Expr', operatora 'Expr' (które są niezmienione, więc zachowują swoje' Span's), nowo utworzone 'MethodCall'' Expr' z 'Span's dla obu 'Expr' i" Ident "metody. To te dwa ostatnie "Span", którymi jestem zainteresowany. – llogiq