1//! A trait that can provide the `Span` of the complete contents of a syntax 2//! tree node. 3//! 4//! <br> 5//! 6//! # Example 7//! 8//! Suppose in a procedural macro we have a [`Type`] that we want to assert 9//! implements the [`Sync`] trait. Maybe this is the type of one of the fields 10//! of a struct for which we are deriving a trait implementation, and we need to 11//! be able to pass a reference to one of those fields across threads. 12//! 13//! [`Type`]: crate::Type 14//! [`Sync`]: std::marker::Sync 15//! 16//! If the field type does *not* implement `Sync` as required, we want the 17//! compiler to report an error pointing out exactly which type it was. 18//! 19//! The following macro code takes a variable `ty` of type `Type` and produces a 20//! static assertion that `Sync` is implemented for that type. 21//! 22//! ``` 23//! # extern crate proc_macro; 24//! # 25//! use proc_macro::TokenStream; 26//! use proc_macro2::Span; 27//! use quote::quote_spanned; 28//! use syn::Type; 29//! use syn::spanned::Spanned; 30//! 31//! # const IGNORE_TOKENS: &str = stringify! { 32//! #[proc_macro_derive(MyMacro)] 33//! # }; 34//! pub fn my_macro(input: TokenStream) -> TokenStream { 35//! # let ty = get_a_type(); 36//! /* ... */ 37//! 38//! let assert_sync = quote_spanned! {ty.span()=> 39//! struct _AssertSync where #ty: Sync; 40//! }; 41//! 42//! /* ... */ 43//! # input 44//! } 45//! # 46//! # fn get_a_type() -> Type { 47//! # unimplemented!() 48//! # } 49//! ``` 50//! 51//! By inserting this `assert_sync` fragment into the output code generated by 52//! our macro, the user's code will fail to compile if `ty` does not implement 53//! `Sync`. The errors they would see look like the following. 54//! 55//! ```text 56//! error[E0277]: the trait bound `*const i32: std::marker::Sync` is not satisfied 57//! --> src/main.rs:10:21 58//! | 59//! 10 | bad_field: *const i32, 60//! | ^^^^^^^^^^ `*const i32` cannot be shared between threads safely 61//! ``` 62//! 63//! In this technique, using the `Type`'s span for the error message makes the 64//! error appear in the correct place underlining the right type. 65//! 66//! <br> 67//! 68//! # Limitations 69//! 70//! The underlying [`proc_macro::Span::join`] method is nightly-only. When 71//! called from within a procedural macro in a nightly compiler, `Spanned` will 72//! use `join` to produce the intended span. When not using a nightly compiler, 73//! only the span of the *first token* of the syntax tree node is returned. 74//! 75//! In the common case of wanting to use the joined span as the span of a 76//! `syn::Error`, consider instead using [`syn::Error::new_spanned`] which is 77//! able to span the error correctly under the complete syntax tree node without 78//! needing the unstable `join`. 79//! 80//! [`syn::Error::new_spanned`]: crate::Error::new_spanned 81 82use proc_macro2::Span; 83use quote::spanned::Spanned as ToTokens; 84 85/// A trait that can provide the `Span` of the complete contents of a syntax 86/// tree node. 87/// 88/// This trait is automatically implemented for all types that implement 89/// [`ToTokens`] from the `quote` crate, as well as for `Span` itself. 90/// 91/// [`ToTokens`]: quote::ToTokens 92/// 93/// See the [module documentation] for an example. 94/// 95/// [module documentation]: self 96pub trait Spanned: private::Sealed { 97 /// Returns a `Span` covering the complete contents of this syntax tree 98 /// node, or [`Span::call_site()`] if this node is empty. 99 /// 100 /// [`Span::call_site()`]: proc_macro2::Span::call_site 101 fn span(&self) -> Span; 102} 103 104impl<T: ?Sized + ToTokens> Spanned for T { 105 fn span(&self) -> Span { 106 self.__span() 107 } 108} 109 110mod private { 111 use super::*; 112 113 pub trait Sealed {} 114 impl<T: ?Sized + ToTokens> Sealed for T {} 115 116 #[cfg(any(feature = "full", feature = "derive"))] 117 impl Sealed for crate::QSelf {} 118} 119