proc-macro-workshop:seq-8
审题
// 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 协议》,转载必须注明作者和本文链接