What is a Span in syn?

I'm trying to create a function arg and other things in syn and often I see a need for a span:

FnArg::Typed(PatType {
                                attrs: vec![],
                                pat: Box::new(Pat::Ident(PatIdent {
                                    attrs: vec![],
                                    by_ref: Some(Ref {
                                        span: ?,
                                    }),
                                    mutability: None,
                                    ident: Ident::new(struct_name.as_str(), ?),
                                    subpat: None,
                                })),
                                colon_token: Colon{
                                    spans: item_impl.,
                                },
                                ty: todo!(),
                            })

which is not even from syn but from proc_macro.

What exactly is a Span and what do I need to put in span above?

1 Like

A span indicates a source location. There are two main functions of spans

  • error messages use spans on certain tokens in order to point to right place in code when reporting on errors
  • name resolution can distinguish variables with the same name based on different spans, this is how macro_rules’ hygiene works, where you can introduce, say, new helper variables in a macro without fearing name collisions (I don’t know the full details on how this all works, especially from the point-of-view of proc-macro implementers, but with this in mind, I suppose you make sure to correctly copy the span for any identifiers in your macro-generated code that you inherit from the user-input to the macro; and also you can use Span::mixed_site() for newly introduced local helper variables to get good hygiene behavior)

For your particular use-case you can either use some sensible span copied from the macro-input, or you can create a new span with Span::call_site() or Span::mixed_site() (which shouldn’t make a difference in this case, I believe). It probably won’t really matter at all in this case where you take your pan from for this ref pattern specifier: really the only effect in this case is where exactly an error message that wants to point to that ref ends up pointing to in the macro caller’s code.

As a point of comparison, code generated using the quote! macro uses Span::call_site() for all newly generated tokens by default.

2 Likes