-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #47099 - SergioBenitez:master, r=jseyfried
Add 'Span::parent()' and 'Span::source()' to proc_macro API. As the title suggests: a couple of useful methods for `proc_macro`.
- Loading branch information
Showing
4 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/test/ui-fulldeps/proc-macro/auxiliary/parent-source-spans.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2018 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, TokenTree, TokenNode, Span}; | ||
|
||
fn lit_span(tt: TokenTree) -> (Span, String) { | ||
use TokenNode::*; | ||
match tt.kind { | ||
Literal(..) | Group(..) => (tt.span, tt.to_string().trim().into()), | ||
_ => panic!("expected a literal in token tree, got: {:?}", tt) | ||
} | ||
} | ||
|
||
#[proc_macro] | ||
pub fn parent_source_spans(input: TokenStream) -> TokenStream { | ||
let mut tokens = input.into_iter(); | ||
let (sp1, str1) = lit_span(tokens.next().expect("first string")); | ||
let _ = tokens.next(); | ||
let (sp2, str2) = lit_span(tokens.next().expect("second string")); | ||
|
||
sp1.error(format!("first final: {}", str1)).emit(); | ||
sp2.error(format!("second final: {}", str2)).emit(); | ||
|
||
if let (Some(p1), Some(p2)) = (sp1.parent(), sp2.parent()) { | ||
p1.error(format!("first parent: {}", str1)).emit(); | ||
p2.error(format!("second parent: {}", str2)).emit(); | ||
|
||
if let (Some(gp1), Some(gp2)) = (p1.parent(), p2.parent()) { | ||
gp1.error(format!("first grandparent: {}", str1)).emit(); | ||
gp2.error(format!("second grandparent: {}", str2)).emit(); | ||
} | ||
} | ||
|
||
sp1.source().error(format!("first source: {}", str1)).emit(); | ||
sp2.source().error(format!("second source: {}", str2)).emit(); | ||
|
||
"ok".parse().unwrap() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright 2018 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:parent-source-spans.rs | ||
// ignore-stage1 | ||
|
||
#![feature(proc_macro, decl_macro)] | ||
|
||
extern crate parent_source_spans; | ||
|
||
use parent_source_spans::parent_source_spans; | ||
|
||
macro one($a:expr, $b:expr) { | ||
two!($a, $b); | ||
//~^ ERROR first parent: "hello" | ||
//~| ERROR second parent: "world" | ||
} | ||
|
||
macro two($a:expr, $b:expr) { | ||
three!($a, $b); | ||
//~^ ERROR first final: "hello" | ||
//~| ERROR second final: "world" | ||
//~| ERROR first final: "yay" | ||
//~| ERROR second final: "rust" | ||
} | ||
|
||
// forwarding tokens directly doesn't create a new source chain | ||
macro three($($tokens:tt)*) { | ||
four!($($tokens)*); | ||
} | ||
|
||
macro four($($tokens:tt)*) { | ||
parent_source_spans!($($tokens)*); | ||
} | ||
|
||
fn main() { | ||
one!("hello", "world"); | ||
//~^ ERROR first grandparent: "hello" | ||
//~| ERROR second grandparent: "world" | ||
//~| ERROR first source: "hello" | ||
//~| ERROR second source: "world" | ||
|
||
two!("yay", "rust"); | ||
//~^ ERROR first parent: "yay" | ||
//~| ERROR second parent: "rust" | ||
//~| ERROR first source: "yay" | ||
//~| ERROR second source: "rust" | ||
|
||
three!("hip", "hop"); | ||
//~^ ERROR first final: "hip" | ||
//~| ERROR second final: "hop" | ||
//~| ERROR first source: "hip" | ||
//~| ERROR second source: "hop" | ||
} |
128 changes: 128 additions & 0 deletions
128
src/test/ui-fulldeps/proc-macro/parent-source-spans.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
error: first final: "hello" | ||
--> $DIR/parent-source-spans.rs:27:12 | ||
| | ||
27 | three!($a, $b); | ||
| ^^ | ||
... | ||
44 | one!("hello", "world"); | ||
| ----------------------- in this macro invocation | ||
|
||
error: second final: "world" | ||
--> $DIR/parent-source-spans.rs:27:16 | ||
| | ||
27 | three!($a, $b); | ||
| ^^ | ||
... | ||
44 | one!("hello", "world"); | ||
| ----------------------- in this macro invocation | ||
|
||
error: first parent: "hello" | ||
--> $DIR/parent-source-spans.rs:21:5 | ||
| | ||
21 | two!($a, $b); | ||
| ^^^^^^^^^^^^^ | ||
... | ||
44 | one!("hello", "world"); | ||
| ----------------------- in this macro invocation | ||
|
||
error: second parent: "world" | ||
--> $DIR/parent-source-spans.rs:21:5 | ||
| | ||
21 | two!($a, $b); | ||
| ^^^^^^^^^^^^^ | ||
... | ||
44 | one!("hello", "world"); | ||
| ----------------------- in this macro invocation | ||
|
||
error: first grandparent: "hello" | ||
--> $DIR/parent-source-spans.rs:44:5 | ||
| | ||
44 | one!("hello", "world"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: second grandparent: "world" | ||
--> $DIR/parent-source-spans.rs:44:5 | ||
| | ||
44 | one!("hello", "world"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: first source: "hello" | ||
--> $DIR/parent-source-spans.rs:44:5 | ||
| | ||
44 | one!("hello", "world"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: second source: "world" | ||
--> $DIR/parent-source-spans.rs:44:5 | ||
| | ||
44 | one!("hello", "world"); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: first final: "yay" | ||
--> $DIR/parent-source-spans.rs:27:12 | ||
| | ||
27 | three!($a, $b); | ||
| ^^ | ||
... | ||
50 | two!("yay", "rust"); | ||
| -------------------- in this macro invocation | ||
|
||
error: second final: "rust" | ||
--> $DIR/parent-source-spans.rs:27:16 | ||
| | ||
27 | three!($a, $b); | ||
| ^^ | ||
... | ||
50 | two!("yay", "rust"); | ||
| -------------------- in this macro invocation | ||
|
||
error: first parent: "yay" | ||
--> $DIR/parent-source-spans.rs:50:5 | ||
| | ||
50 | two!("yay", "rust"); | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: second parent: "rust" | ||
--> $DIR/parent-source-spans.rs:50:5 | ||
| | ||
50 | two!("yay", "rust"); | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: first source: "yay" | ||
--> $DIR/parent-source-spans.rs:50:5 | ||
| | ||
50 | two!("yay", "rust"); | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: second source: "rust" | ||
--> $DIR/parent-source-spans.rs:50:5 | ||
| | ||
50 | two!("yay", "rust"); | ||
| ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: first final: "hip" | ||
--> $DIR/parent-source-spans.rs:56:12 | ||
| | ||
56 | three!("hip", "hop"); | ||
| ^^^^^ | ||
|
||
error: second final: "hop" | ||
--> $DIR/parent-source-spans.rs:56:19 | ||
| | ||
56 | three!("hip", "hop"); | ||
| ^^^^^ | ||
|
||
error: first source: "hip" | ||
--> $DIR/parent-source-spans.rs:56:12 | ||
| | ||
56 | three!("hip", "hop"); | ||
| ^^^^^ | ||
|
||
error: second source: "hop" | ||
--> $DIR/parent-source-spans.rs:56:19 | ||
| | ||
56 | three!("hip", "hop"); | ||
| ^^^^^ | ||
|
||
error: aborting due to 18 previous errors | ||
|