Skip to content
This repository has been archived by the owner on Oct 6, 2024. It is now read-only.

Commit

Permalink
Simplify signature of paste_segments to share with doc codepath
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Oct 21, 2020
1 parent fe7898b commit e4b1f66
Showing 1 changed file with 25 additions and 12 deletions.
37 changes: 25 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ use crate::doc::{do_paste_doc, is_pasted_doc};
use crate::error::{Error, Result};
use crate::segment::Segment;
use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
use std::iter::{self, FromIterator};
use std::iter;
use std::panic;

#[proc_macro]
Expand Down Expand Up @@ -199,8 +199,9 @@ fn expand(input: TokenStream, contains_paste: &mut bool) -> Result<TokenStream>
let span = group.span();
if delimiter == Delimiter::Bracket && is_paste_operation(&content) {
let segments = parse_bracket_as_segments(content, span)?;
let pasted = paste_segments(span, &segments)?;
expanded.extend(pasted);
let pasted = paste_segments(&segments)?;
let tokens = pasted_to_tokens(pasted, span)?;
expanded.extend(tokens);
*contains_paste = true;
} else if delimiter == Delimiter::None && is_flat_group(&content) {
expanded.extend(content);
Expand Down Expand Up @@ -348,7 +349,7 @@ fn parse_bracket_as_segments(input: TokenStream, scope: Span) -> Result<Vec<Segm
}
}

fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
fn paste_segments(segments: &[Segment]) -> Result<String> {
let mut evaluated = Vec::new();
let mut is_lifetime = false;

Expand Down Expand Up @@ -435,7 +436,23 @@ fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
}
}

let pasted = evaluated.into_iter().collect::<String>();
let mut pasted = evaluated.into_iter().collect::<String>();
if is_lifetime {
pasted.insert(0, '\'');
}
Ok(pasted)
}

fn pasted_to_tokens(mut pasted: String, span: Span) -> Result<TokenStream> {
let mut tokens = TokenStream::new();

if pasted.starts_with('\'') {
let mut apostrophe = TokenTree::Punct(Punct::new('\'', Spacing::Joint));
apostrophe.set_span(span);
tokens.extend(iter::once(apostrophe));
pasted.remove(0);
}

let ident = match panic::catch_unwind(|| Ident::new(&pasted, span)) {
Ok(ident) => TokenTree::Ident(ident),
Err(_) => {
Expand All @@ -445,11 +462,7 @@ fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
));
}
};
let tokens = if is_lifetime {
let apostrophe = TokenTree::Punct(Punct::new('\'', Spacing::Joint));
vec![apostrophe, ident]
} else {
vec![ident]
};
Ok(TokenStream::from_iter(tokens))

tokens.extend(iter::once(ident));
Ok(tokens)
}

0 comments on commit e4b1f66

Please sign in to comment.