From 00a4ad198745b44751dad89c4e8409ac76d7b738 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Mon, 25 Sep 2023 18:12:03 +0200 Subject: [PATCH] Perform own detection for proc_macro_span (fixes #39) --- genco-macros/build.rs | 35 ++++++++++++++++++++++++++++++ genco-macros/src/fake.rs | 47 ++++++++++++++++++++++++++++------------ genco-macros/src/lib.rs | 1 + 3 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 genco-macros/build.rs diff --git a/genco-macros/build.rs b/genco-macros/build.rs new file mode 100644 index 0000000..b486454 --- /dev/null +++ b/genco-macros/build.rs @@ -0,0 +1,35 @@ +use std::env; +use std::process::Command; +use std::str; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + let version = rustc_version().unwrap_or(RustcVersion { + minor: u32::MAX, + nightly: false, + }); + + if version.nightly { + println!("cargo:rustc-cfg=proc_macro_span"); + } +} + +struct RustcVersion { + #[allow(unused)] + minor: u32, + nightly: bool, +} + +fn rustc_version() -> Option { + let rustc = env::var_os("RUSTC")?; + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let nightly = version.contains("nightly") || version.contains("dev"); + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + let minor = pieces.next()?.parse().ok()?; + Some(RustcVersion { minor, nightly }) +} diff --git a/genco-macros/src/fake.rs b/genco-macros/src/fake.rs index a78ab91..1bcb5f7 100644 --- a/genco-macros/src/fake.rs +++ b/genco-macros/src/fake.rs @@ -17,12 +17,35 @@ pub(crate) struct LineColumn { } impl LineColumn { - fn new(line_column: proc_macro2::LineColumn) -> Self { + #[cfg(proc_macro_span)] + fn from_start(span: Span) -> Self { + let span = span.unwrap().start(); + Self { - line: line_column.line, - column: line_column.column, + line: span.line(), + column: span.column(), } } + + #[cfg(proc_macro_span)] + fn from_end(span: Span) -> Self { + let span = span.unwrap().end(); + + Self { + line: span.line(), + column: span.column(), + } + } + + #[cfg(not(proc_macro_span))] + fn from_start(span: Span) -> Self { + Self { line: 0, column: 0 } + } + + #[cfg(not(proc_macro_span))] + fn from_end(span: Span) -> Self { + Self { line: 0, column: 0 } + } } #[derive(Default)] @@ -42,8 +65,8 @@ impl Buf { /// Construct a cursor from a span. pub(crate) fn cursor(&mut self, span: Span) -> syn::Result { - let start = span.start(); - let end = span.end(); + let start = LineColumn::from_start(span); + let end = LineColumn::from_end(span); if (start.line == 0 && start.column == 0) || (end.line == 0 && end.column == 0) { // Try compat. @@ -61,17 +84,13 @@ impl Buf { }, )) } else { - Ok(Cursor::new( - span, - LineColumn::new(start), - LineColumn::new(end), - )) + Ok(Cursor::new(span, start, end)) } } /// The start of the given span. pub(crate) fn start(&mut self, span: Span) -> syn::Result { - let start = span.start(); + let start = LineColumn::from_start(span); // Try to use compat layer. if start.line == 0 && start.column == 0 { @@ -79,13 +98,13 @@ impl Buf { let (column, _) = self.find_line_column(span)?; Ok(LineColumn { line: 1, column }) } else { - Ok(LineColumn::new(start)) + Ok(start) } } /// The start of the given span. pub(crate) fn end(&mut self, span: Span) -> syn::Result { - let end = span.end(); + let end = LineColumn::from_end(span); // Try to use compat layer. if end.line == 0 && end.column == 0 { @@ -93,7 +112,7 @@ impl Buf { let (_, column) = self.find_line_column(span)?; Ok(LineColumn { line: 1, column }) } else { - Ok(LineColumn::new(end)) + Ok(end) } } diff --git a/genco-macros/src/lib.rs b/genco-macros/src/lib.rs index 6d7b5c5..7a9a68c 100644 --- a/genco-macros/src/lib.rs +++ b/genco-macros/src/lib.rs @@ -4,6 +4,7 @@ #![recursion_limit = "256"] #![allow(clippy::type_complexity)] +#![cfg_attr(proc_macro_span, feature(proc_macro_span))] extern crate proc_macro;