Description
Updated description
The following procedural macro:
#![feature(proc_macro)]
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
let mut body = Vec::<TokenTree>::new();
// input = `let a = 2;`
body.extend(input.into_iter());
// manually add `let b = a;`
body.push(Term::new("let", Span::call_site()).into());
body.push(Term::new("b", Span::call_site()).into());
body.push(Op::new('=', Spacing::Alone).into());
body.push(Term::new("a", Span::call_site()).into());
body.push(Op::new(';', Spacing::Alone).into());
// parse and add `let c = b;`
body.extend("let c = b;".parse::<TokenStream>().unwrap().into_iter());
let mut ret = Vec::<TokenTree>::new();
ret.push(Term::new("fn", Span::call_site()).into());
ret.push(Term::new("main", Span::call_site()).into());
ret.push(Group::new(Delimiter::Parenthesis, TokenStream::empty()).into());
ret.push(Group::new(Delimiter::Brace, body.into_iter().collect()).into());
ret.into_iter().collect()
}
fails when invoked as:
#![feature(proc_macro)]
extern crate foo;
foo::foo! {
let a = 3;
}
with the error message:
error[E0425]: cannot find value `b` in this scope
--> src/main.rs:6:1
|
6 | / foo::foo! {
7 | | let a = 3;
8 | | }
| |_^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
Original description
Linking the futures-await
crate and a crate that useserror-chain-derive
together breaks the build. Here's a simple example: https://github.com/golddranks/test_futures_await_error_chain_derive Either of the two dependencies (futures-await
and dotenv
, which uses error-chain-derive
) builds on its own (using the latest nightly), but together they refuse to build.
This seems to have something to do with the defsite hygiene: error-chain-derive
is using derive macros 1.1, and the syntax for using it is as follows: (from https://github.com/purpliminal/rust-dotenv/blob/master/src/errors.rs )
#[derive(Debug, ErrorChain)]
#[cfg_attr(not(feature = "backtrace"), error_chain(backtrace = "false"))]
pub enum ErrorKind {
// generic error string, required by derive_error_chain
Msg(String),
#[error_chain(custom)]
#[error_chain(description = r#"|_| "Parsing Error""#)]
#[error_chain(display = r#"|l| write!(f, "Error parsing line: '{}'", l)"#)]
LineParse(String),
#[error_chain(foreign)]
Io(::std::io::Error),
#[error_chain(foreign)]
EnvVar(::std::env::VarError),
}
|l| write!(f, "Error parsing line: '{}'", l)
breaks, because it can't find f
: cannot find value f in this scope
It seems like just the presence of futures-await
somehow affects how the Derive macros 1.1 hygiene works; however, the derive macros are stable, so this is an undesirable thing.