diff --git a/Cargo.lock b/Cargo.lock index 67df4d6..804d4c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1536,7 +1536,8 @@ dependencies = [ [[package]] name = "proc-macro2" version = "1.0.67" -source = "git+https://github.com/tonyg/proc-macro2?branch=repair_span_start_end#e1af85d3dd6ad595cedc0c344418ab0a60f1ce72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] diff --git a/Cargo.toml b/Cargo.toml index 185503b..75c7372 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,8 +26,8 @@ strip = true [profile.bench] debug = true -[patch.crates-io] -# Unfortunately, until [1] is fixed (perhaps via [2]), we have to use a patched proc-macro2. -# [1]: https://github.com/dtolnay/proc-macro2/issues/402 -# [2]: https://github.com/dtolnay/proc-macro2/pull/407 -proc-macro2 = { git = "https://github.com/tonyg/proc-macro2", branch = "repair_span_start_end" } +# [patch.crates-io] +# # Unfortunately, until [1] is fixed (perhaps via [2]), we have to use a patched proc-macro2. +# # [1]: https://github.com/dtolnay/proc-macro2/issues/402 +# # [2]: https://github.com/dtolnay/proc-macro2/pull/407 +# proc-macro2 = { git = "https://github.com/tonyg/proc-macro2", branch = "repair_span_start_end" } diff --git a/syndicate-macros/src/stx.rs b/syndicate-macros/src/stx.rs index 8ec7a1d..9df186a 100644 --- a/syndicate-macros/src/stx.rs +++ b/syndicate-macros/src/stx.rs @@ -1,5 +1,6 @@ use proc_macro2::Delimiter; use proc_macro2::LineColumn; +use proc_macro2::Span; use proc_macro2::TokenStream; use syn::ExprLit; @@ -70,24 +71,41 @@ fn punct_char(c: Cursor) -> Option<(char, Cursor)> { c.punct().map(|(p, c)| (p.as_char(), c)) } +fn start_pos(s: Span) -> LineColumn { + // We would like to write + // s.start() + // here, but until [1] is fixed (perhaps via [2]), we have to go the unsafe route + // and assume we are in procedural macro context. + // [1]: https://github.com/dtolnay/proc-macro2/issues/402 + // [2]: https://github.com/dtolnay/proc-macro2/pull/407 + let u = s.unwrap().start(); + LineColumn { column: u.column(), line: u.line() } +} + +fn end_pos(s: Span) -> LineColumn { + // See start_pos + let u = s.unwrap().end(); + LineColumn { column: u.column(), line: u.line() } +} + fn parse_id(mut c: Cursor) -> Result<(String, Cursor)> { let mut id = String::new(); - let mut prev_pos = c.span().start(); + let mut prev_pos = start_pos(c.span()); loop { - if c.eof() || c.span().start() != prev_pos { + if c.eof() || start_pos(c.span()) != prev_pos { return Ok((id, c)); } else if let Some((p, next)) = c.punct() { match p.as_char() { '<' | '>' | '(' | ')' | '{' | '}' | '[' | ']' | ',' | ':' => return Ok((id, c)), ch => { id.push(ch); - prev_pos = c.span().end(); + prev_pos = end_pos(c.span()); c = next; } } } else if let Some((i, next)) = c.ident() { id.push_str(&i.to_string()); - prev_pos = i.span().end(); + prev_pos = end_pos(i.span()); c = next; } else { return Ok((id, c)); @@ -153,7 +171,7 @@ fn parse_kv(c: Cursor) -> Result<((Stx, Stx), Cursor)> { } fn adjacent_ident(pos: LineColumn, c: Cursor) -> (Option, Cursor) { - if c.span().start() != pos { + if start_pos(c.span()) != pos { (None, c) } else if let Some((id, next)) = c.ident() { (Some(id), next) @@ -177,8 +195,8 @@ fn parse_generic(mut c: Cursor) -> Option<(T, Cursor)> { // OK, because parse2 checks for end-of-stream, let's chop // the input at the position of the error and try again (!). let mut collected = Vec::new(); - let upto = e.span().start(); - while !c.eof() && c.span().start() != upto { + let upto = start_pos(e.span()); + while !c.eof() && start_pos(c.span()) != upto { let (tt, next) = c.token_tree().unwrap(); collected.push(tt); c = next; @@ -200,7 +218,7 @@ fn parse1(c: Cursor) -> Result<(Stx, Cursor)> { Ok((Stx::Rec(Box::new(q.remove(0)), q), c)) }), '$' => { - let (maybe_id, next) = adjacent_ident(p.span().end(), next); + let (maybe_id, next) = adjacent_ident(end_pos(p.span()), next); let (maybe_type, next) = if let Some((':', next)) = punct_char(next) { match parse_generic::(next) { Some((t, next)) => (Some(t), next),