diff --git a/build.rs b/build.rs index deb9b927..a06f009c 100644 --- a/build.rs +++ b/build.rs @@ -57,6 +57,10 @@ fn main() { println!("cargo:rustc-cfg=span_locations"); } + if version.minor >= 45 { + println!("cargo:rustc-cfg=hygiene"); + } + let target = env::var("TARGET").unwrap(); if !enable_use_proc_macro(&target) { return; diff --git a/src/fallback.rs b/src/fallback.rs index fffea68f..554c87ea 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -374,6 +374,11 @@ impl Span { Span { lo: 0, hi: 0 } } + #[cfg(hygiene)] + pub fn mixed_site() -> Span { + Span::call_site() + } + #[cfg(procmacro2_semver_exempt)] pub fn def_site() -> Span { Span::call_site() diff --git a/src/lib.rs b/src/lib.rs index 23b2c266..725e1214 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -348,6 +348,16 @@ impl Span { Span::_new(imp::Span::call_site()) } + /// The span located at the invocation of the procedural macro, but with + /// local variables, labels, and `$crate` resolved at the definition site + /// of the macro. This is the same hygiene behavior as `macro_rules`. + /// + /// This function requires Rust 1.45 or later. + #[cfg(hygiene)] + pub fn mixed_site() -> Span { + Span::_new(imp::Span::mixed_site()) + } + /// A span that resolves at the macro definition site. /// /// This method is semver exempt and not exposed by default. diff --git a/src/wrapper.rs b/src/wrapper.rs index 1887d8e2..f9429b7b 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -376,6 +376,15 @@ impl Span { } } + #[cfg(hygiene)] + pub fn mixed_site() -> Span { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::mixed_site()) + } else { + Span::Fallback(fallback::Span::mixed_site()) + } + } + #[cfg(super_unstable)] pub fn def_site() -> Span { if inside_proc_macro() {