Repository: dtolnay/paste (rust)

Issue:
Pasted identifier may not refer to a captured local variable
This is a consequence of hygiene rules.

```rust
extern crate paste;

fn main() {
    let yy = 0;

    paste::expr! {
        println!("{}", [<y y>]);
    }
}
```

```console
error[E0425]: cannot find value `yy` in this scope                                                                             
 --> src/main.rs:6:5                                                                                                           
  |                                                                                                                            
6 | /     paste::expr! {                                                                                                       
7 | |         println!("{}", [<y y>]);                                                                                         
8 | |     }                                                                                                                    
  | |_____^ not found in this scope
```

Pull request description:
Ability to refer to local variables
Fixes #1.

Patch:
diff --git a/README.md b/README.md
index 176ad16..8245f55 100644
--- a/README.md
+++ b/README.md
@@ -120,13 +120,6 @@ fn call_some_getters(s: &S) -> bool {
 }
 ```
 
-## Limitations
-
-- As a consequence of hygiene, a concatenated identifier may not be used to
-  refer to a captured local variable ([#1]).
-
-[#1]: https://github.com/dtolnay/paste/issues/1
-
 <br>
 
 #### License
diff --git a/impl/src/lib.rs b/impl/src/lib.rs
index f15f356..fbeb0a7 100644
--- a/impl/src/lib.rs
+++ b/impl/src/lib.rs
@@ -39,7 +39,7 @@ impl Parse for PasteInput {
                     let span = group.span();
                     if delimiter == Delimiter::Bracket && is_paste_operation(&content) {
                         let segments = parse_bracket_as_segments.parse2(content)?;
-                        let pasted = paste_segments(&segments)?;
+                        let pasted = paste_segments(span, &segments)?;
                         pasted.to_tokens(&mut expanded);
                     } else {
                         let nested = PasteInput::parse.parse2(content)?;
@@ -123,7 +123,7 @@ fn parse_segments(input: ParseStream) -> Result<Vec<Segment>> {
     Ok(segments)
 }
 
-fn paste_segments(segments: &[Segment]) -> Result<TokenStream> {
+fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
     let mut pasted = String::new();
     let mut is_lifetime = false;
 
@@ -151,7 +151,7 @@ fn paste_segments(segments: &[Segment]) -> Result<TokenStream> {
         }
     }
 
-    let ident = TokenTree::Ident(Ident::new(&pasted, Span::call_site()));
+    let ident = TokenTree::Ident(Ident::new(&pasted, span));
     let tokens = if is_lifetime {
         let apostrophe = TokenTree::Punct(Punct::new('\'', Spacing::Joint));
         vec![apostrophe, ident]
diff --git a/src/lib.rs b/src/lib.rs
index 2243523..d6d013b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -109,13 +109,6 @@
 //! #
 //! # fn main() {}
 //! ```
-//!
-//! # Limitations
-//!
-//! - As a consequence of hygiene, a concatenated identifier may not be used to
-//!   refer to a captured local variable ([#1]).
-//!
-//! [#1]: https://github.com/dtolnay/paste/issues/1
 
 extern crate paste_impl;
 extern crate proc_macro_hack;


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 9e82c1e..014d117 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -145,3 +145,12 @@ fn test_false_start() {
         assert_eq!(x[0], 0);
     }
 }
+
+#[test]
+fn test_local_variable() {
+    let yy = 0;
+
+    paste::expr! {
+        assert_eq!([<y y>], 0);
+    }
+}