Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to strip doc / attributes info from the Span #1488

Closed
Mingun opened this issue Jul 18, 2023 · 1 comment
Closed

Add ability to strip doc / attributes info from the Span #1488

Mingun opened this issue Jul 18, 2023 · 1 comment

Comments

@Mingun
Copy link

Mingun commented Jul 18, 2023

I'm working on and PR for fixing serde-rs/serde#2105 and the related stuff and making compiletests for them. For the piece

#[derive(Serialize)]
#[serde(tag = "type")]
enum Serializable {
    /// Error should be reported
    Tuple2(u8, u8),
}

the error span would cover several lines:

error: #[serde(tag = "...")] cannot be used with tuple variants
  --> tests/ui/enum-representation/internal-tuple-variant.rs:10:5
   |
10 | /     /// Error should be reported
11 | |     Tuple2(u8, u8),
   | |__________________^

Because doc comments can be very long, it is impractical to bring them into error messages. I would like to get the following message:

error: #[serde(tag = "...")] cannot be used with tuple variants
  --> tests/ui/enum-representation/internal-tuple-variant.rs:10:5
   |
10 |       /// Error should be reported
11 |       Tuple2(u8, u8),
   |       ^^^^^^^^^^^^^^

That error is generated by the following code in serde (here in action):

// variant.original is a `&syn::Variant`
cx.error_spanned_by(
    variant.original,
    "#[serde(tag = \"...\")] cannot be used with tuple variants",
);

Is there any way to strip span that related to doc comments (and probably to all other attributes) and keep only code span of syn::Variant, syn::Field, etc?

@dtolnay
Copy link
Owner

dtolnay commented Apr 18, 2024

The range that the error points to is determined by providing a ToTokens implementation that contains the tokens which are to be highlighted in the error. So for this case, something like:

let error = syn::Error::new_spanned(
    WithoutAttrs(variant.original),
    "...",
);

where the ToTokens impl is:

struct WithoutAttrs<T>(T);

impl ToTokens for WithoutAttrs<&syn::Variant> {
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        self.0.ident.to_tokens(tokens);
        self.0.fields.to_tokens(tokens);
    }
}

@dtolnay dtolnay closed this as completed Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants