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