Repariert "keine Regeln erwartet den Token" -Makrofehler

8

Ich versuche ein Makro zum Destrukturieren von BSON-Daten zu schreiben, das so aussieht:

%Vor%

Ich habe das folgende Makro (ziemlich groß) dafür geschrieben:

%Vor%

Das erste Beispiel führt jedoch zu folgendem Kompilierungsfehler:

%Vor%

Ich bin etwas überrascht, dass es den Fehlerort nicht wie üblich anzeigt (das heißt, es gibt keinen Hinweis darauf, wo eine Erweiterung stattfindet), der Fehler verschwindet jedoch, wenn ich den Codeabschnitt, der das Makro verwendet, kommentiere.

Ich kann nicht sehen, warum es sagt, dass keine Regeln dieses Token erwarten, weil es eine solche Regel gibt, aber vielleicht verstehe ich etwas nicht.

Ich bin mir ziemlich sicher, dass das möglich ist, weil das in etwa die quick_error-Kiste ist, aber es scheint, dass meine Makro-Schreibfähigkeiten noch fehlen.

Wie sollte ich das Makro reparieren, damit es wie erwartet funktioniert?

Der Vollständigkeit halber lautet die folgende Definition von BsonDestructureError :

%Vor%

Ich benutze auch bson crate reexported von ejdb crate. Hier ist ein minimales Beispiel, das mit cargo script auf stabilem Rust.

    
Vladimir Matveev 09.01.2016, 13:09
quelle

1 Antwort

12

Sowohl cargo script , ein rekursiver Muncher, und meine bevorzugte interne Regelsyntax; Wie kann ich nicht?

Zunächst kann das genaue Problem durch Ausführen von cargo rustc -- -Z trace-macros identifiziert werden. Dadurch wird jede Regel ausgegeben, sobald sie erweitert wird. Dies gibt uns ein "Backtrace", das nach einer manuellen Neuformatierung folgendermaßen aussieht:

%Vor%

Ein sorgfältiges Studium der Regeln in bson_destructure! zeigt das Problem: Es gibt keine Regel, die der dritten Erweiterung entspricht. macro_rules! ist, offen gesagt, Müll bei der Meldung von fehlerhaften Stellen, wenn es um rekursive Regeln geht; dass es auf das opt -Token zeigt, ist irrelevant. Das echte Problem besteht darin, dass keine übereinstimmende Regel gefunden werden konnte.

Insbesondere ist die verletzende Regel diese:

%Vor%

Beachten Sie das Vorhandensein eines Kommas unmittelbar nach $nv:ident . Beachten Sie auch, dass kein solches Komma in der Eingabe ist. Dies kann gelöst werden, indem das Komma innerhalb der Wiederholung wie folgt verschoben wird:

%Vor%

Eine andere Alternative (und die, mit der ich normalerweise gehe) besteht darin, die Eingabe einfach zu mutieren, wenn sie zum ersten Mal auftritt, um sicherzustellen, dass immer ein nachkommendes Komma ist.

Der Code wird aufgrund einer nativen Abhängigkeit nicht wirklich auf meinem Rechner kompiliert , aber ich habe überprüft, ob diese Änderung (sowohl hier als auch bei den anderen Regeln mit einem ähnlichen Problem) möglich ist es, um Makroexpansion abzuschließen. Sie können überprüfen, ob die Ausgabe korrekt aussieht, indem Sie cargo rustc -- -Z unstable-options --pretty=expanded verwenden.

    
DK. 09.01.2016, 13:39
quelle

Tags und Links