Refactor to keep up with changes to proc_macro#122
Conversation
| quote!({ | ||
| extern crate maud; | ||
| let mut $output_ident = String::with_capacity($size_hint as usize); | ||
| //let mut $output_ident = String::with_capacity($size_hint as usize); |
There was a problem hiding this comment.
The compiler complains about $size_hint here
|
@lfairy This compiles, but I have introduced some parsing errors in the process. My hope is that we can work through these and keep the broad structure of the code intact. |
|
I don't have time to look at this yet, but if you change the |
| tts.extend(i); | ||
| } | ||
|
|
||
| tts.into_iter().collect() |
There was a problem hiding this comment.
I believe this change can be reverted once rust-lang/rust#49734 lands
|
|
||
| fn match_arms(&mut self) -> ParseResult<TokenStream> { | ||
| let mut arms = Vec::new(); | ||
| let mut arms: Vec<TokenTree> = Vec::new(); |
|
Life on the bleeding edge! 🐎 💨 |
|
I think we're close. Tests pass for me locally, but on CI the hyper dependency doesn't compile. I'll clean up warnings and try to work it out. There are newer releases of hyper: https://github.com/hyperium/hyper/releases |
|
Clippy failing on Hyper is a known issue (rust-lang/rust#49643; there's a Clippy issue as well but I can't find it right now). Since it's not our fault I think we can ignore it for now 🙂 |
|
Alrighty. I'll squash these down. |
aee31d4 to
716824a
Compare
Instead of a `kind` field containting a `TokenNode` variant, a TokenTree is now an enum with variants of different types (Literal, Op, Term, etc). Note that a TokenTree could be a sequence of TokenTrees if it is a Group variant. Other notes: I'm unsure about the set_span call in Builder::emit_if, but I did not want to throw away the passed in Span. Parsing relies on destructuring references to the values associated with TokenTree enum variants It doesn't seem as easy to compose/chain TokenStreams as it is to collect a Vec<TokenTree> into a TokenStream. There is probably some iterator API I could use instead. See `match_arms` and build.rs Refs lambda-fairy#121
716824a to
0f453a5
Compare
|
rust-lang/rust#49734 was merged 21 hours ago. I think we might need to wait another day before it's in nightly. |
Also remove conservative_impl_trait feature flag, as this is now a stable feature. Refs lambda-fairy#121
|
I've addressed the previous comments now that the iterator changes have landed. |
lambda-fairy
left a comment
There was a problem hiding this comment.
Thanks for sticking through with this!
I have a few comments to make, but as they're pretty minor I'll merge your changes as-is and fix it up myself.
| }); | ||
| let mut g = Group::new(Delimiter::Parenthesis, cond); | ||
| // NOTE: Do we need to do this? | ||
| g.set_span(cond_span); |
There was a problem hiding this comment.
To be honest I'm not actually sure 😛
My original thought was that using the source spans more often would improve compiler diagnostics. But since we're creating these parentheses out of whole cloth it's a bit questionable to use them here.
I'm in the process of rewriting this file in another branch, so I'll address this point there.
| if cond.clone().into_iter().any(|token| match token.kind { | ||
| TokenNode::Group(Delimiter::Brace, _) => true, | ||
| if cond.clone().into_iter().any(|token| match token { | ||
| TokenTree::Group(grp) => { |
There was a problem hiding this comment.
In general I tend to avoid minor abbreviations like this.
cond is okay because condition is pretty long. But group vs grp isn't such a clear win.
(I realize I abbreviate pattern to pat elsewhere... should probably fix that)
| /// Indicates whether we're inside an attribute node. | ||
| in_attr: bool, | ||
| input: TokenTreeIter, | ||
| input: token_stream::IntoIter, |
There was a problem hiding this comment.
<TokenStream as IntoIterator>::IntoIter will avoid the import (as well as signal our intentions more clearly)
| // When emitting a `@let`, wrap the rest of the block in a | ||
| // new block to avoid scoping issues | ||
| let keyword = TokenTree { kind: TokenNode::Term(term), span }; | ||
| let keyword = Term::new(term.as_str(), term.span()); |
There was a problem hiding this comment.
The old code did this term wrapping dance because the identifier and span used to be in separate fields, such that matching the term required pulling it apart and putting it back together again.
But now that the Term data type contains its own span, we can use the original term without the dance.
| let block = self.block(grp.stream(), grp.span())?; | ||
| builder.push(block); | ||
| }, | ||
| _ => { return self.error("expected body for @else"); }, |
There was a problem hiding this comment.
return is an expression -- you can omit the braces if it's the only thing in the block:
_ => return self.error("..."),| kind: TokenNode::Group(Delimiter::Brace, builder.build()), | ||
| span, | ||
| }) | ||
| Ok(TokenTree::Group(Group::new(Delimiter::Brace, builder.build()))) |
There was a problem hiding this comment.
This code should call .set_span() on the generated Group

Instead of a
kindfield containting aTokenNodevariant, aTokenTree is now an enum with variants of different types (Literal, Op,
Term, etc). Note that a TokenTree could be a sequence of TokenTrees if it is a
Group variant.
Other notes:
I'm unsure about the set_span call in Builder::emit_if, but I did not want to
throw away the passed in Span.
Parsing relies on destructuring references to the values associated with
TokenTree enum variants
Refs #121