preserve delim spans during macro_rules!
expansion if able
This commit is contained in:
parent
b9e8286c85
commit
31443c63b5
4 changed files with 30 additions and 23 deletions
|
@ -10,7 +10,7 @@ use crate::mbe::transcribe::transcribe;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
|
||||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
|
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
||||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_attr::{self as attr, TransparencyError};
|
use rustc_attr::{self as attr, TransparencyError};
|
||||||
|
@ -212,7 +212,6 @@ fn expand_macro<'cx>(
|
||||||
};
|
};
|
||||||
let arm_span = rhses[i].span();
|
let arm_span = rhses[i].span();
|
||||||
|
|
||||||
let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::<Vec<_>>();
|
|
||||||
// rhs has holes ( `$id` and `$(...)` that need filled)
|
// rhs has holes ( `$id` and `$(...)` that need filled)
|
||||||
let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
|
let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) {
|
||||||
Ok(tts) => tts,
|
Ok(tts) => tts,
|
||||||
|
@ -224,12 +223,25 @@ fn expand_macro<'cx>(
|
||||||
|
|
||||||
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
// Replace all the tokens for the corresponding positions in the macro, to maintain
|
||||||
// proper positions in error reporting, while maintaining the macro_backtrace.
|
// proper positions in error reporting, while maintaining the macro_backtrace.
|
||||||
if rhs_spans.len() == tts.len() {
|
if tts.len() == rhs.tts.len() {
|
||||||
tts = tts.map_enumerated(|i, tt| {
|
tts = tts.map_enumerated(|i, tt| {
|
||||||
let mut tt = tt.clone();
|
let mut tt = tt.clone();
|
||||||
let mut sp = rhs_spans[i];
|
let rhs_tt = &rhs.tts[i];
|
||||||
sp = sp.with_ctxt(tt.span().ctxt());
|
let ctxt = tt.span().ctxt();
|
||||||
tt.set_span(sp);
|
match (&mut tt, rhs_tt) {
|
||||||
|
// preserve the delim spans if able
|
||||||
|
(
|
||||||
|
TokenTree::Delimited(target_sp, ..),
|
||||||
|
mbe::TokenTree::Delimited(source_sp, ..),
|
||||||
|
) => {
|
||||||
|
target_sp.open = source_sp.open.with_ctxt(ctxt);
|
||||||
|
target_sp.close = source_sp.close.with_ctxt(ctxt);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let sp = rhs_tt.span().with_ctxt(ctxt);
|
||||||
|
tt.set_span(sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
tt
|
tt
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> {
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
...
|
...
|
||||||
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
|
| ^ expected type
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -22,26 +22,21 @@ LL | Example::<gimme_a_const!(marker)>
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
...
|
...
|
||||||
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type
|
| ^ expected type
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: expected type, found `{`
|
error: expected type, found `{`
|
||||||
--> $DIR/macro-fail.rs:4:10
|
--> $DIR/macro-fail.rs:4:10
|
||||||
|
|
|
|
||||||
LL | () => {{
|
LL | () => {{
|
||||||
| __________^
|
| ^ expected type
|
||||||
LL | |
|
|
||||||
LL | | const X: usize = 1337;
|
|
||||||
LL | | X
|
|
||||||
LL | | }}
|
|
||||||
| |___^ expected type
|
|
||||||
...
|
...
|
||||||
LL | let _fail = Example::<external_macro!()>;
|
LL | let _fail = Example::<external_macro!()>;
|
||||||
| -----------------
|
| -----------------
|
||||||
| |
|
| |
|
||||||
| this macro call doesn't expand to a type
|
| this macro call doesn't expand to a type
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `{`
|
||||||
--> $DIR/import-prefix-macro-1.rs:11:27
|
--> $DIR/import-prefix-macro-1.rs:11:27
|
||||||
|
|
|
|
||||||
LL | ($p: path) => (use $p {S, Z});
|
LL | ($p: path) => (use $p {S, Z});
|
||||||
| ^^^^^^ expected one of `::`, `;`, or `as`
|
| ^ expected one of `::`, `;`, or `as`
|
||||||
...
|
...
|
||||||
LL | import! { a::b::c }
|
LL | import! { a::b::c }
|
||||||
| ------------------- in this macro invocation
|
| ------------------- in this macro invocation
|
||||||
|
|
|
@ -21,8 +21,8 @@ LL | foo!(true);
|
||||||
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
help: if `bar` is a struct, use braces as delimiters
|
help: if `bar` is a struct, use braces as delimiters
|
||||||
|
|
|
|
||||||
LL | bar { }
|
LL | bar { baz: $rest }
|
||||||
| ~
|
| ~ ~
|
||||||
help: if `bar` is a function, use the arguments directly
|
help: if `bar` is a function, use the arguments directly
|
||||||
|
|
|
|
||||||
LL - bar(baz: $rest)
|
LL - bar(baz: $rest)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue