Initial diagnostic API for proc-macros.
This commit introduces the ability to create and emit `Diagnostic` structures from proc-macros, allowing for proc-macro authors to emit warning, error, note, and help messages just like the compiler does.
This commit is contained in:
parent
a0c3bd2d23
commit
8be132e9d7
9 changed files with 314 additions and 1 deletions
56
src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs
Normal file
56
src/test/ui-fulldeps/proc-macro/auxiliary/three-equals.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::{TokenStream, TokenNode, Span, Diagnostic};
|
||||
|
||||
fn parse(input: TokenStream) -> Result<(), Diagnostic> {
|
||||
let mut count = 0;
|
||||
let mut last_span = Span::default();
|
||||
for tree in input {
|
||||
let span = tree.span;
|
||||
if count >= 3 {
|
||||
return Err(span.error(format!("expected EOF, found `{}`.", tree))
|
||||
.span_note(last_span, "last good input was here")
|
||||
.help("input must be: `===`"))
|
||||
}
|
||||
|
||||
if let TokenNode::Op('=', _) = tree.kind {
|
||||
count += 1;
|
||||
} else {
|
||||
return Err(span.error(format!("expected `=`, found `{}`.", tree)));
|
||||
}
|
||||
|
||||
last_span = span;
|
||||
}
|
||||
|
||||
if count < 3 {
|
||||
return Err(Span::default()
|
||||
.error(format!("found {} equal signs, need exactly 3", count))
|
||||
.help("input must be: `===`"))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn three_equals(input: TokenStream) -> TokenStream {
|
||||
if let Err(diag) = parse(input) {
|
||||
diag.emit();
|
||||
return TokenStream::empty();
|
||||
}
|
||||
|
||||
"3".parse().unwrap()
|
||||
}
|
||||
38
src/test/ui-fulldeps/proc-macro/three-equals.rs
Normal file
38
src/test/ui-fulldeps/proc-macro/three-equals.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:three-equals.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate three_equals;
|
||||
|
||||
use three_equals::three_equals;
|
||||
|
||||
fn main() {
|
||||
// This one is okay.
|
||||
three_equals!(===);
|
||||
|
||||
// Need exactly three equals.
|
||||
three_equals!(==);
|
||||
|
||||
// Need exactly three equals.
|
||||
three_equals!(=====);
|
||||
|
||||
// Only equals accepted.
|
||||
three_equals!(abc);
|
||||
|
||||
// Only equals accepted.
|
||||
three_equals!(!!);
|
||||
|
||||
// Only three characters expected.
|
||||
three_equals!(===a);
|
||||
}
|
||||
48
src/test/ui-fulldeps/proc-macro/three-equals.stderr
Normal file
48
src/test/ui-fulldeps/proc-macro/three-equals.stderr
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
error: found 2 equal signs, need exactly 3
|
||||
--> $DIR/three-equals.rs:25:5
|
||||
|
|
||||
25 | three_equals!(==);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: input must be: `===`
|
||||
|
||||
error: expected EOF, found `=`.
|
||||
--> $DIR/three-equals.rs:28:21
|
||||
|
|
||||
28 | three_equals!(=====);
|
||||
| ^^
|
||||
|
|
||||
note: last good input was here
|
||||
--> $DIR/three-equals.rs:28:21
|
||||
|
|
||||
28 | three_equals!(=====);
|
||||
| ^^
|
||||
= help: input must be: `===`
|
||||
|
||||
error: expected `=`, found `abc`.
|
||||
--> $DIR/three-equals.rs:31:19
|
||||
|
|
||||
31 | three_equals!(abc);
|
||||
| ^^^
|
||||
|
||||
error: expected `=`, found `!`.
|
||||
--> $DIR/three-equals.rs:34:19
|
||||
|
|
||||
34 | three_equals!(!!);
|
||||
| ^
|
||||
|
||||
error: expected EOF, found `a`.
|
||||
--> $DIR/three-equals.rs:37:22
|
||||
|
|
||||
37 | three_equals!(===a);
|
||||
| ^
|
||||
|
|
||||
note: last good input was here
|
||||
--> $DIR/three-equals.rs:37:21
|
||||
|
|
||||
37 | three_equals!(===a);
|
||||
| ^
|
||||
= help: input must be: `===`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue