// The procedural macro API uses a type called Span to attach source location
// and hygiene information to every token. In order for compiler errors to
// appear underlining the right places, procedural macros are responsible for
// propagating and manipulating these spans correctly.
//
// The invocation below expands to code that mentions a value Missing0 which
// does not exist. When the compiler reports that it "cannot find value
// Missing0", we would like for the error to point directly to where the user
// wrote `Missing~N` in their macro input.
//
// error[E0425]: cannot find value `Missing0` in this scope
// |
// | let _ = Missing~N;
// | ^^^^^^^ not found in this scope
//
// For this test to pass, ensure that the pasted-together identifier is created
// using the Span of the identifier written by the caller.
//
// If you are using a nightly toolchain, there is a nightly-only method called
// Span::join which would allow joining the three spans of `Missing`, `~`, `N`
// so that the resulting error is as follows, but I would recommend not
// bothering with this for the purpose of this project while it is unstable.
//
// error[E0425]: cannot find value `Missing0` in this scope
// |
// | let _ = Missing~N;
// | ^^^^^^^^^ not found in this scope
//
use seq::seq;
seq!(N in 0..1 {
fn main() {
let _ = Missing~N;
}
});
這裡考察的還是報錯位置的解析,也就是span
。
error[E0425]: cannot find value `Missing0` in this scope
--> tests/08-ident-span.rs:34:17
|
34 | let _ = Missing~N;
| ^^^^^^^ not found in this scope
因為對於N in 0..1
後續{}
內部的解析,我們都是基於標準的rust
語法。
型別未定義這種情況,是必定能夠解析出來的。
從這裡也能夠看出來rust
強大的一方面,靜態檢查能夠規避大多數開發問題。
編譯期間,只要有良好、準確的錯誤提示,即使是macro
中的自定義語句,也能夠進行錯誤的定位。
雖然span
資訊的處理讓人覺得雞肋,但是完整的檢查,可以讓使用者在開發過程中,在一無所知的宏定義中,得到正確的指引。
本作品採用《CC 協議》,轉載必須註明作者和本文連結