proc_macro: Add an expand_expr method to TokenStream
This feature is aimed at giving proc macros access to powers similar to those used by builtin macros such as `format_args!` or `concat!`. These macros are able to accept macros in place of string literal parameters, such as the format string, as they perform recursive macro expansion while being expanded. This can be especially useful in many cases thanks to helper macros like `concat!`, `stringify!` and `include_str!` which are often used to construct string literals at compile-time in user code. For now, this method only allows expanding macros which produce literals, although more expresisons will be supported before the method is stabilized.
This commit is contained in:
parent
800a156c1e
commit
3e4d3d2a29
8 changed files with 421 additions and 75 deletions
|
@ -24,8 +24,9 @@ impl base::ProcMacro for BangProcMacro {
|
|||
span: Span,
|
||||
input: TokenStream,
|
||||
) -> Result<TokenStream, ErrorReported> {
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
let server = proc_macro_server::Rustc::new(ecx);
|
||||
self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace).map_err(|e| {
|
||||
self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
|
||||
let mut err = ecx.struct_span_err(span, "proc macro panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
err.help(&format!("message: {}", s));
|
||||
|
@ -48,9 +49,10 @@ impl base::AttrProcMacro for AttrProcMacro {
|
|||
annotation: TokenStream,
|
||||
annotated: TokenStream,
|
||||
) -> Result<TokenStream, ErrorReported> {
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
let server = proc_macro_server::Rustc::new(ecx);
|
||||
self.client
|
||||
.run(&EXEC_STRATEGY, server, annotation, annotated, ecx.ecfg.proc_macro_backtrace)
|
||||
.run(&EXEC_STRATEGY, server, annotation, annotated, proc_macro_backtrace)
|
||||
.map_err(|e| {
|
||||
let mut err = ecx.struct_span_err(span, "custom attribute panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
|
@ -97,19 +99,19 @@ impl MultiItemModifier for ProcMacroDerive {
|
|||
nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
|
||||
};
|
||||
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
let server = proc_macro_server::Rustc::new(ecx);
|
||||
let stream =
|
||||
match self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace) {
|
||||
Ok(stream) => stream,
|
||||
Err(e) => {
|
||||
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
err.help(&format!("message: {}", s));
|
||||
}
|
||||
err.emit();
|
||||
return ExpandResult::Ready(vec![]);
|
||||
let stream = match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
|
||||
Ok(stream) => stream,
|
||||
Err(e) => {
|
||||
let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
|
||||
if let Some(s) = e.as_str() {
|
||||
err.help(&format!("message: {}", s));
|
||||
}
|
||||
};
|
||||
err.emit();
|
||||
return ExpandResult::Ready(vec![]);
|
||||
}
|
||||
};
|
||||
|
||||
let error_count_before = ecx.sess.parse_sess.span_diagnostic.err_count();
|
||||
let mut parser =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue