1*69942c0aSMiguel Ojeda // SPDX-License-Identifier: Apache-2.0 OR MIT
2*69942c0aSMiguel Ojeda
3808c999fSMiguel Ojeda #[cfg(feature = "parsing")]
4808c999fSMiguel Ojeda use crate::buffer::Cursor;
5808c999fSMiguel Ojeda use crate::thread::ThreadBound;
6808c999fSMiguel Ojeda use proc_macro2::{
7808c999fSMiguel Ojeda Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
8808c999fSMiguel Ojeda };
9808c999fSMiguel Ojeda #[cfg(feature = "printing")]
10808c999fSMiguel Ojeda use quote::ToTokens;
11808c999fSMiguel Ojeda use std::fmt::{self, Debug, Display};
12808c999fSMiguel Ojeda use std::slice;
13808c999fSMiguel Ojeda use std::vec;
14808c999fSMiguel Ojeda
15808c999fSMiguel Ojeda /// The result of a Syn parser.
16808c999fSMiguel Ojeda pub type Result<T> = std::result::Result<T, Error>;
17808c999fSMiguel Ojeda
18808c999fSMiguel Ojeda /// Error returned when a Syn parser cannot parse the input tokens.
19808c999fSMiguel Ojeda ///
20808c999fSMiguel Ojeda /// # Error reporting in proc macros
21808c999fSMiguel Ojeda ///
22808c999fSMiguel Ojeda /// The correct way to report errors back to the compiler from a procedural
23808c999fSMiguel Ojeda /// macro is by emitting an appropriately spanned invocation of
24808c999fSMiguel Ojeda /// [`compile_error!`] in the generated code. This produces a better diagnostic
25808c999fSMiguel Ojeda /// message than simply panicking the macro.
26808c999fSMiguel Ojeda ///
27808c999fSMiguel Ojeda /// [`compile_error!`]: std::compile_error!
28808c999fSMiguel Ojeda ///
29808c999fSMiguel Ojeda /// When parsing macro input, the [`parse_macro_input!`] macro handles the
30808c999fSMiguel Ojeda /// conversion to `compile_error!` automatically.
31808c999fSMiguel Ojeda ///
32808c999fSMiguel Ojeda /// [`parse_macro_input!`]: crate::parse_macro_input!
33808c999fSMiguel Ojeda ///
34808c999fSMiguel Ojeda /// ```
35808c999fSMiguel Ojeda /// # extern crate proc_macro;
36808c999fSMiguel Ojeda /// #
37808c999fSMiguel Ojeda /// use proc_macro::TokenStream;
38808c999fSMiguel Ojeda /// use syn::parse::{Parse, ParseStream, Result};
39808c999fSMiguel Ojeda /// use syn::{parse_macro_input, ItemFn};
40808c999fSMiguel Ojeda ///
41808c999fSMiguel Ojeda /// # const IGNORE: &str = stringify! {
42808c999fSMiguel Ojeda /// #[proc_macro_attribute]
43808c999fSMiguel Ojeda /// # };
44808c999fSMiguel Ojeda /// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream {
45808c999fSMiguel Ojeda /// let args = parse_macro_input!(args as MyAttrArgs);
46808c999fSMiguel Ojeda /// let input = parse_macro_input!(input as ItemFn);
47808c999fSMiguel Ojeda ///
48808c999fSMiguel Ojeda /// /* ... */
49808c999fSMiguel Ojeda /// # TokenStream::new()
50808c999fSMiguel Ojeda /// }
51808c999fSMiguel Ojeda ///
52808c999fSMiguel Ojeda /// struct MyAttrArgs {
53808c999fSMiguel Ojeda /// # _k: [(); { stringify! {
54808c999fSMiguel Ojeda /// ...
55808c999fSMiguel Ojeda /// # }; 0 }]
56808c999fSMiguel Ojeda /// }
57808c999fSMiguel Ojeda ///
58808c999fSMiguel Ojeda /// impl Parse for MyAttrArgs {
59808c999fSMiguel Ojeda /// fn parse(input: ParseStream) -> Result<Self> {
60808c999fSMiguel Ojeda /// # stringify! {
61808c999fSMiguel Ojeda /// ...
62808c999fSMiguel Ojeda /// # };
63808c999fSMiguel Ojeda /// # unimplemented!()
64808c999fSMiguel Ojeda /// }
65808c999fSMiguel Ojeda /// }
66808c999fSMiguel Ojeda /// ```
67808c999fSMiguel Ojeda ///
68808c999fSMiguel Ojeda /// For errors that arise later than the initial parsing stage, the
69808c999fSMiguel Ojeda /// [`.to_compile_error()`] or [`.into_compile_error()`] methods can be used to
70808c999fSMiguel Ojeda /// perform an explicit conversion to `compile_error!`.
71808c999fSMiguel Ojeda ///
72808c999fSMiguel Ojeda /// [`.to_compile_error()`]: Error::to_compile_error
73808c999fSMiguel Ojeda /// [`.into_compile_error()`]: Error::into_compile_error
74808c999fSMiguel Ojeda ///
75808c999fSMiguel Ojeda /// ```
76808c999fSMiguel Ojeda /// # extern crate proc_macro;
77808c999fSMiguel Ojeda /// #
78808c999fSMiguel Ojeda /// # use proc_macro::TokenStream;
79808c999fSMiguel Ojeda /// # use syn::{parse_macro_input, DeriveInput};
80808c999fSMiguel Ojeda /// #
81808c999fSMiguel Ojeda /// # const IGNORE: &str = stringify! {
82808c999fSMiguel Ojeda /// #[proc_macro_derive(MyDerive)]
83808c999fSMiguel Ojeda /// # };
84808c999fSMiguel Ojeda /// pub fn my_derive(input: TokenStream) -> TokenStream {
85808c999fSMiguel Ojeda /// let input = parse_macro_input!(input as DeriveInput);
86808c999fSMiguel Ojeda ///
87808c999fSMiguel Ojeda /// // fn(DeriveInput) -> syn::Result<proc_macro2::TokenStream>
88808c999fSMiguel Ojeda /// expand::my_derive(input)
89808c999fSMiguel Ojeda /// .unwrap_or_else(syn::Error::into_compile_error)
90808c999fSMiguel Ojeda /// .into()
91808c999fSMiguel Ojeda /// }
92808c999fSMiguel Ojeda /// #
93808c999fSMiguel Ojeda /// # mod expand {
94808c999fSMiguel Ojeda /// # use proc_macro2::TokenStream;
95808c999fSMiguel Ojeda /// # use syn::{DeriveInput, Result};
96808c999fSMiguel Ojeda /// #
97808c999fSMiguel Ojeda /// # pub fn my_derive(input: DeriveInput) -> Result<TokenStream> {
98808c999fSMiguel Ojeda /// # unimplemented!()
99808c999fSMiguel Ojeda /// # }
100808c999fSMiguel Ojeda /// # }
101808c999fSMiguel Ojeda /// ```
102808c999fSMiguel Ojeda pub struct Error {
103808c999fSMiguel Ojeda messages: Vec<ErrorMessage>,
104808c999fSMiguel Ojeda }
105808c999fSMiguel Ojeda
106808c999fSMiguel Ojeda struct ErrorMessage {
107808c999fSMiguel Ojeda // Span is implemented as an index into a thread-local interner to keep the
108808c999fSMiguel Ojeda // size small. It is not safe to access from a different thread. We want
109808c999fSMiguel Ojeda // errors to be Send and Sync to play nicely with ecosystem crates for error
110808c999fSMiguel Ojeda // handling, so pin the span we're given to its original thread and assume
111808c999fSMiguel Ojeda // it is Span::call_site if accessed from any other thread.
112808c999fSMiguel Ojeda span: ThreadBound<SpanRange>,
113808c999fSMiguel Ojeda message: String,
114808c999fSMiguel Ojeda }
115808c999fSMiguel Ojeda
116808c999fSMiguel Ojeda // Cannot use std::ops::Range<Span> because that does not implement Copy,
117808c999fSMiguel Ojeda // whereas ThreadBound<T> requires a Copy impl as a way to ensure no Drop impls
118808c999fSMiguel Ojeda // are involved.
119808c999fSMiguel Ojeda struct SpanRange {
120808c999fSMiguel Ojeda start: Span,
121808c999fSMiguel Ojeda end: Span,
122808c999fSMiguel Ojeda }
123808c999fSMiguel Ojeda
124808c999fSMiguel Ojeda #[cfg(test)]
125808c999fSMiguel Ojeda struct _Test
126808c999fSMiguel Ojeda where
127808c999fSMiguel Ojeda Error: Send + Sync;
128808c999fSMiguel Ojeda
129808c999fSMiguel Ojeda impl Error {
130808c999fSMiguel Ojeda /// Usually the [`ParseStream::error`] method will be used instead, which
131808c999fSMiguel Ojeda /// automatically uses the correct span from the current position of the
132808c999fSMiguel Ojeda /// parse stream.
133808c999fSMiguel Ojeda ///
134808c999fSMiguel Ojeda /// Use `Error::new` when the error needs to be triggered on some span other
135808c999fSMiguel Ojeda /// than where the parse stream is currently positioned.
136808c999fSMiguel Ojeda ///
137808c999fSMiguel Ojeda /// [`ParseStream::error`]: crate::parse::ParseBuffer::error
138808c999fSMiguel Ojeda ///
139808c999fSMiguel Ojeda /// # Example
140808c999fSMiguel Ojeda ///
141808c999fSMiguel Ojeda /// ```
142808c999fSMiguel Ojeda /// use syn::{Error, Ident, LitStr, Result, Token};
143808c999fSMiguel Ojeda /// use syn::parse::ParseStream;
144808c999fSMiguel Ojeda ///
145808c999fSMiguel Ojeda /// // Parses input that looks like `name = "string"` where the key must be
146808c999fSMiguel Ojeda /// // the identifier `name` and the value may be any string literal.
147808c999fSMiguel Ojeda /// // Returns the string literal.
148808c999fSMiguel Ojeda /// fn parse_name(input: ParseStream) -> Result<LitStr> {
149808c999fSMiguel Ojeda /// let name_token: Ident = input.parse()?;
150808c999fSMiguel Ojeda /// if name_token != "name" {
151808c999fSMiguel Ojeda /// // Trigger an error not on the current position of the stream,
152808c999fSMiguel Ojeda /// // but on the position of the unexpected identifier.
153808c999fSMiguel Ojeda /// return Err(Error::new(name_token.span(), "expected `name`"));
154808c999fSMiguel Ojeda /// }
155808c999fSMiguel Ojeda /// input.parse::<Token![=]>()?;
156808c999fSMiguel Ojeda /// let s: LitStr = input.parse()?;
157808c999fSMiguel Ojeda /// Ok(s)
158808c999fSMiguel Ojeda /// }
159808c999fSMiguel Ojeda /// ```
new<T: Display>(span: Span, message: T) -> Self160808c999fSMiguel Ojeda pub fn new<T: Display>(span: Span, message: T) -> Self {
161808c999fSMiguel Ojeda return new(span, message.to_string());
162808c999fSMiguel Ojeda
163808c999fSMiguel Ojeda fn new(span: Span, message: String) -> Error {
164808c999fSMiguel Ojeda Error {
165808c999fSMiguel Ojeda messages: vec![ErrorMessage {
166808c999fSMiguel Ojeda span: ThreadBound::new(SpanRange {
167808c999fSMiguel Ojeda start: span,
168808c999fSMiguel Ojeda end: span,
169808c999fSMiguel Ojeda }),
170808c999fSMiguel Ojeda message,
171808c999fSMiguel Ojeda }],
172808c999fSMiguel Ojeda }
173808c999fSMiguel Ojeda }
174808c999fSMiguel Ojeda }
175808c999fSMiguel Ojeda
176808c999fSMiguel Ojeda /// Creates an error with the specified message spanning the given syntax
177808c999fSMiguel Ojeda /// tree node.
178808c999fSMiguel Ojeda ///
179808c999fSMiguel Ojeda /// Unlike the `Error::new` constructor, this constructor takes an argument
180808c999fSMiguel Ojeda /// `tokens` which is a syntax tree node. This allows the resulting `Error`
181808c999fSMiguel Ojeda /// to attempt to span all tokens inside of `tokens`. While you would
182808c999fSMiguel Ojeda /// typically be able to use the `Spanned` trait with the above `Error::new`
183808c999fSMiguel Ojeda /// constructor, implementation limitations today mean that
184808c999fSMiguel Ojeda /// `Error::new_spanned` may provide a higher-quality error message on
185808c999fSMiguel Ojeda /// stable Rust.
186808c999fSMiguel Ojeda ///
187808c999fSMiguel Ojeda /// When in doubt it's recommended to stick to `Error::new` (or
188808c999fSMiguel Ojeda /// `ParseStream::error`)!
189808c999fSMiguel Ojeda #[cfg(feature = "printing")]
190808c999fSMiguel Ojeda #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
new_spanned<T: ToTokens, U: Display>(tokens: T, message: U) -> Self191808c999fSMiguel Ojeda pub fn new_spanned<T: ToTokens, U: Display>(tokens: T, message: U) -> Self {
192808c999fSMiguel Ojeda return new_spanned(tokens.into_token_stream(), message.to_string());
193808c999fSMiguel Ojeda
194808c999fSMiguel Ojeda fn new_spanned(tokens: TokenStream, message: String) -> Error {
195808c999fSMiguel Ojeda let mut iter = tokens.into_iter();
196808c999fSMiguel Ojeda let start = iter.next().map_or_else(Span::call_site, |t| t.span());
197808c999fSMiguel Ojeda let end = iter.last().map_or(start, |t| t.span());
198808c999fSMiguel Ojeda Error {
199808c999fSMiguel Ojeda messages: vec![ErrorMessage {
200808c999fSMiguel Ojeda span: ThreadBound::new(SpanRange { start, end }),
201808c999fSMiguel Ojeda message,
202808c999fSMiguel Ojeda }],
203808c999fSMiguel Ojeda }
204808c999fSMiguel Ojeda }
205808c999fSMiguel Ojeda }
206808c999fSMiguel Ojeda
207808c999fSMiguel Ojeda /// The source location of the error.
208808c999fSMiguel Ojeda ///
209808c999fSMiguel Ojeda /// Spans are not thread-safe so this function returns `Span::call_site()`
210808c999fSMiguel Ojeda /// if called from a different thread than the one on which the `Error` was
211808c999fSMiguel Ojeda /// originally created.
span(&self) -> Span212808c999fSMiguel Ojeda pub fn span(&self) -> Span {
213808c999fSMiguel Ojeda let SpanRange { start, end } = match self.messages[0].span.get() {
214808c999fSMiguel Ojeda Some(span) => *span,
215808c999fSMiguel Ojeda None => return Span::call_site(),
216808c999fSMiguel Ojeda };
217808c999fSMiguel Ojeda start.join(end).unwrap_or(start)
218808c999fSMiguel Ojeda }
219808c999fSMiguel Ojeda
220808c999fSMiguel Ojeda /// Render the error as an invocation of [`compile_error!`].
221808c999fSMiguel Ojeda ///
222808c999fSMiguel Ojeda /// The [`parse_macro_input!`] macro provides a convenient way to invoke
223808c999fSMiguel Ojeda /// this method correctly in a procedural macro.
224808c999fSMiguel Ojeda ///
225808c999fSMiguel Ojeda /// [`compile_error!`]: std::compile_error!
226808c999fSMiguel Ojeda /// [`parse_macro_input!`]: crate::parse_macro_input!
to_compile_error(&self) -> TokenStream227808c999fSMiguel Ojeda pub fn to_compile_error(&self) -> TokenStream {
228808c999fSMiguel Ojeda self.messages
229808c999fSMiguel Ojeda .iter()
230808c999fSMiguel Ojeda .map(ErrorMessage::to_compile_error)
231808c999fSMiguel Ojeda .collect()
232808c999fSMiguel Ojeda }
233808c999fSMiguel Ojeda
234808c999fSMiguel Ojeda /// Render the error as an invocation of [`compile_error!`].
235808c999fSMiguel Ojeda ///
236808c999fSMiguel Ojeda /// [`compile_error!`]: std::compile_error!
237808c999fSMiguel Ojeda ///
238808c999fSMiguel Ojeda /// # Example
239808c999fSMiguel Ojeda ///
240808c999fSMiguel Ojeda /// ```
241808c999fSMiguel Ojeda /// # extern crate proc_macro;
242808c999fSMiguel Ojeda /// #
243808c999fSMiguel Ojeda /// use proc_macro::TokenStream;
244808c999fSMiguel Ojeda /// use syn::{parse_macro_input, DeriveInput, Error};
245808c999fSMiguel Ojeda ///
246808c999fSMiguel Ojeda /// # const _: &str = stringify! {
247808c999fSMiguel Ojeda /// #[proc_macro_derive(MyTrait)]
248808c999fSMiguel Ojeda /// # };
249808c999fSMiguel Ojeda /// pub fn derive_my_trait(input: TokenStream) -> TokenStream {
250808c999fSMiguel Ojeda /// let input = parse_macro_input!(input as DeriveInput);
251808c999fSMiguel Ojeda /// my_trait::expand(input)
252808c999fSMiguel Ojeda /// .unwrap_or_else(Error::into_compile_error)
253808c999fSMiguel Ojeda /// .into()
254808c999fSMiguel Ojeda /// }
255808c999fSMiguel Ojeda ///
256808c999fSMiguel Ojeda /// mod my_trait {
257808c999fSMiguel Ojeda /// use proc_macro2::TokenStream;
258808c999fSMiguel Ojeda /// use syn::{DeriveInput, Result};
259808c999fSMiguel Ojeda ///
260808c999fSMiguel Ojeda /// pub(crate) fn expand(input: DeriveInput) -> Result<TokenStream> {
261808c999fSMiguel Ojeda /// /* ... */
262808c999fSMiguel Ojeda /// # unimplemented!()
263808c999fSMiguel Ojeda /// }
264808c999fSMiguel Ojeda /// }
265808c999fSMiguel Ojeda /// ```
into_compile_error(self) -> TokenStream266808c999fSMiguel Ojeda pub fn into_compile_error(self) -> TokenStream {
267808c999fSMiguel Ojeda self.to_compile_error()
268808c999fSMiguel Ojeda }
269808c999fSMiguel Ojeda
270808c999fSMiguel Ojeda /// Add another error message to self such that when `to_compile_error()` is
271808c999fSMiguel Ojeda /// called, both errors will be emitted together.
combine(&mut self, another: Error)272808c999fSMiguel Ojeda pub fn combine(&mut self, another: Error) {
273808c999fSMiguel Ojeda self.messages.extend(another.messages);
274808c999fSMiguel Ojeda }
275808c999fSMiguel Ojeda }
276808c999fSMiguel Ojeda
277808c999fSMiguel Ojeda impl ErrorMessage {
to_compile_error(&self) -> TokenStream278808c999fSMiguel Ojeda fn to_compile_error(&self) -> TokenStream {
279808c999fSMiguel Ojeda let (start, end) = match self.span.get() {
280808c999fSMiguel Ojeda Some(range) => (range.start, range.end),
281808c999fSMiguel Ojeda None => (Span::call_site(), Span::call_site()),
282808c999fSMiguel Ojeda };
283808c999fSMiguel Ojeda
284808c999fSMiguel Ojeda // ::core::compile_error!($message)
285808c999fSMiguel Ojeda TokenStream::from_iter([
286808c999fSMiguel Ojeda TokenTree::Punct({
287808c999fSMiguel Ojeda let mut punct = Punct::new(':', Spacing::Joint);
288808c999fSMiguel Ojeda punct.set_span(start);
289808c999fSMiguel Ojeda punct
290808c999fSMiguel Ojeda }),
291808c999fSMiguel Ojeda TokenTree::Punct({
292808c999fSMiguel Ojeda let mut punct = Punct::new(':', Spacing::Alone);
293808c999fSMiguel Ojeda punct.set_span(start);
294808c999fSMiguel Ojeda punct
295808c999fSMiguel Ojeda }),
296808c999fSMiguel Ojeda TokenTree::Ident(Ident::new("core", start)),
297808c999fSMiguel Ojeda TokenTree::Punct({
298808c999fSMiguel Ojeda let mut punct = Punct::new(':', Spacing::Joint);
299808c999fSMiguel Ojeda punct.set_span(start);
300808c999fSMiguel Ojeda punct
301808c999fSMiguel Ojeda }),
302808c999fSMiguel Ojeda TokenTree::Punct({
303808c999fSMiguel Ojeda let mut punct = Punct::new(':', Spacing::Alone);
304808c999fSMiguel Ojeda punct.set_span(start);
305808c999fSMiguel Ojeda punct
306808c999fSMiguel Ojeda }),
307808c999fSMiguel Ojeda TokenTree::Ident(Ident::new("compile_error", start)),
308808c999fSMiguel Ojeda TokenTree::Punct({
309808c999fSMiguel Ojeda let mut punct = Punct::new('!', Spacing::Alone);
310808c999fSMiguel Ojeda punct.set_span(start);
311808c999fSMiguel Ojeda punct
312808c999fSMiguel Ojeda }),
313808c999fSMiguel Ojeda TokenTree::Group({
314808c999fSMiguel Ojeda let mut group = Group::new(Delimiter::Brace, {
315808c999fSMiguel Ojeda TokenStream::from_iter([TokenTree::Literal({
316808c999fSMiguel Ojeda let mut string = Literal::string(&self.message);
317808c999fSMiguel Ojeda string.set_span(end);
318808c999fSMiguel Ojeda string
319808c999fSMiguel Ojeda })])
320808c999fSMiguel Ojeda });
321808c999fSMiguel Ojeda group.set_span(end);
322808c999fSMiguel Ojeda group
323808c999fSMiguel Ojeda }),
324808c999fSMiguel Ojeda ])
325808c999fSMiguel Ojeda }
326808c999fSMiguel Ojeda }
327808c999fSMiguel Ojeda
328808c999fSMiguel Ojeda #[cfg(feature = "parsing")]
new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error329808c999fSMiguel Ojeda pub(crate) fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
330808c999fSMiguel Ojeda if cursor.eof() {
331808c999fSMiguel Ojeda Error::new(scope, format!("unexpected end of input, {}", message))
332808c999fSMiguel Ojeda } else {
333808c999fSMiguel Ojeda let span = crate::buffer::open_span_of_group(cursor);
334808c999fSMiguel Ojeda Error::new(span, message)
335808c999fSMiguel Ojeda }
336808c999fSMiguel Ojeda }
337808c999fSMiguel Ojeda
338808c999fSMiguel Ojeda #[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))]
new2<T: Display>(start: Span, end: Span, message: T) -> Error339808c999fSMiguel Ojeda pub(crate) fn new2<T: Display>(start: Span, end: Span, message: T) -> Error {
340808c999fSMiguel Ojeda return new2(start, end, message.to_string());
341808c999fSMiguel Ojeda
342808c999fSMiguel Ojeda fn new2(start: Span, end: Span, message: String) -> Error {
343808c999fSMiguel Ojeda Error {
344808c999fSMiguel Ojeda messages: vec![ErrorMessage {
345808c999fSMiguel Ojeda span: ThreadBound::new(SpanRange { start, end }),
346808c999fSMiguel Ojeda message,
347808c999fSMiguel Ojeda }],
348808c999fSMiguel Ojeda }
349808c999fSMiguel Ojeda }
350808c999fSMiguel Ojeda }
351808c999fSMiguel Ojeda
352808c999fSMiguel Ojeda impl Debug for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result353808c999fSMiguel Ojeda fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
354808c999fSMiguel Ojeda if self.messages.len() == 1 {
355808c999fSMiguel Ojeda formatter
356808c999fSMiguel Ojeda .debug_tuple("Error")
357808c999fSMiguel Ojeda .field(&self.messages[0])
358808c999fSMiguel Ojeda .finish()
359808c999fSMiguel Ojeda } else {
360808c999fSMiguel Ojeda formatter
361808c999fSMiguel Ojeda .debug_tuple("Error")
362808c999fSMiguel Ojeda .field(&self.messages)
363808c999fSMiguel Ojeda .finish()
364808c999fSMiguel Ojeda }
365808c999fSMiguel Ojeda }
366808c999fSMiguel Ojeda }
367808c999fSMiguel Ojeda
368808c999fSMiguel Ojeda impl Debug for ErrorMessage {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result369808c999fSMiguel Ojeda fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
370808c999fSMiguel Ojeda Debug::fmt(&self.message, formatter)
371808c999fSMiguel Ojeda }
372808c999fSMiguel Ojeda }
373808c999fSMiguel Ojeda
374808c999fSMiguel Ojeda impl Display for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result375808c999fSMiguel Ojeda fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
376808c999fSMiguel Ojeda formatter.write_str(&self.messages[0].message)
377808c999fSMiguel Ojeda }
378808c999fSMiguel Ojeda }
379808c999fSMiguel Ojeda
380808c999fSMiguel Ojeda impl Clone for Error {
clone(&self) -> Self381808c999fSMiguel Ojeda fn clone(&self) -> Self {
382808c999fSMiguel Ojeda Error {
383808c999fSMiguel Ojeda messages: self.messages.clone(),
384808c999fSMiguel Ojeda }
385808c999fSMiguel Ojeda }
386808c999fSMiguel Ojeda }
387808c999fSMiguel Ojeda
388808c999fSMiguel Ojeda impl Clone for ErrorMessage {
clone(&self) -> Self389808c999fSMiguel Ojeda fn clone(&self) -> Self {
390808c999fSMiguel Ojeda ErrorMessage {
391808c999fSMiguel Ojeda span: self.span,
392808c999fSMiguel Ojeda message: self.message.clone(),
393808c999fSMiguel Ojeda }
394808c999fSMiguel Ojeda }
395808c999fSMiguel Ojeda }
396808c999fSMiguel Ojeda
397808c999fSMiguel Ojeda impl Clone for SpanRange {
clone(&self) -> Self398808c999fSMiguel Ojeda fn clone(&self) -> Self {
399808c999fSMiguel Ojeda *self
400808c999fSMiguel Ojeda }
401808c999fSMiguel Ojeda }
402808c999fSMiguel Ojeda
403808c999fSMiguel Ojeda impl Copy for SpanRange {}
404808c999fSMiguel Ojeda
405808c999fSMiguel Ojeda impl std::error::Error for Error {}
406808c999fSMiguel Ojeda
407808c999fSMiguel Ojeda impl From<LexError> for Error {
from(err: LexError) -> Self408808c999fSMiguel Ojeda fn from(err: LexError) -> Self {
409808c999fSMiguel Ojeda Error::new(err.span(), err)
410808c999fSMiguel Ojeda }
411808c999fSMiguel Ojeda }
412808c999fSMiguel Ojeda
413808c999fSMiguel Ojeda impl IntoIterator for Error {
414808c999fSMiguel Ojeda type Item = Error;
415808c999fSMiguel Ojeda type IntoIter = IntoIter;
416808c999fSMiguel Ojeda
into_iter(self) -> Self::IntoIter417808c999fSMiguel Ojeda fn into_iter(self) -> Self::IntoIter {
418808c999fSMiguel Ojeda IntoIter {
419808c999fSMiguel Ojeda messages: self.messages.into_iter(),
420808c999fSMiguel Ojeda }
421808c999fSMiguel Ojeda }
422808c999fSMiguel Ojeda }
423808c999fSMiguel Ojeda
424808c999fSMiguel Ojeda pub struct IntoIter {
425808c999fSMiguel Ojeda messages: vec::IntoIter<ErrorMessage>,
426808c999fSMiguel Ojeda }
427808c999fSMiguel Ojeda
428808c999fSMiguel Ojeda impl Iterator for IntoIter {
429808c999fSMiguel Ojeda type Item = Error;
430808c999fSMiguel Ojeda
next(&mut self) -> Option<Self::Item>431808c999fSMiguel Ojeda fn next(&mut self) -> Option<Self::Item> {
432808c999fSMiguel Ojeda Some(Error {
433808c999fSMiguel Ojeda messages: vec![self.messages.next()?],
434808c999fSMiguel Ojeda })
435808c999fSMiguel Ojeda }
436808c999fSMiguel Ojeda }
437808c999fSMiguel Ojeda
438808c999fSMiguel Ojeda impl<'a> IntoIterator for &'a Error {
439808c999fSMiguel Ojeda type Item = Error;
440808c999fSMiguel Ojeda type IntoIter = Iter<'a>;
441808c999fSMiguel Ojeda
into_iter(self) -> Self::IntoIter442808c999fSMiguel Ojeda fn into_iter(self) -> Self::IntoIter {
443808c999fSMiguel Ojeda Iter {
444808c999fSMiguel Ojeda messages: self.messages.iter(),
445808c999fSMiguel Ojeda }
446808c999fSMiguel Ojeda }
447808c999fSMiguel Ojeda }
448808c999fSMiguel Ojeda
449808c999fSMiguel Ojeda pub struct Iter<'a> {
450808c999fSMiguel Ojeda messages: slice::Iter<'a, ErrorMessage>,
451808c999fSMiguel Ojeda }
452808c999fSMiguel Ojeda
453808c999fSMiguel Ojeda impl<'a> Iterator for Iter<'a> {
454808c999fSMiguel Ojeda type Item = Error;
455808c999fSMiguel Ojeda
next(&mut self) -> Option<Self::Item>456808c999fSMiguel Ojeda fn next(&mut self) -> Option<Self::Item> {
457808c999fSMiguel Ojeda Some(Error {
458808c999fSMiguel Ojeda messages: vec![self.messages.next()?.clone()],
459808c999fSMiguel Ojeda })
460808c999fSMiguel Ojeda }
461808c999fSMiguel Ojeda }
462808c999fSMiguel Ojeda
463808c999fSMiguel Ojeda impl Extend<Error> for Error {
extend<T: IntoIterator<Item = Error>>(&mut self, iter: T)464808c999fSMiguel Ojeda fn extend<T: IntoIterator<Item = Error>>(&mut self, iter: T) {
465808c999fSMiguel Ojeda for err in iter {
466808c999fSMiguel Ojeda self.combine(err);
467808c999fSMiguel Ojeda }
468808c999fSMiguel Ojeda }
469808c999fSMiguel Ojeda }
470