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

Expose access to line and column info from SourceSpan #258

Closed
MariaSolOs opened this issue Apr 30, 2023 · 3 comments
Closed

Expose access to line and column info from SourceSpan #258

MariaSolOs opened this issue Apr 30, 2023 · 3 comments

Comments

@MariaSolOs
Copy link

Maybe I'm missing something (and my apologies if that's the case) but when using fancy diagnostics, miette will compute the line and column for display purposes, and it feels reasonable to expose access to these values to avoid unnecessary computations of the same information.

This is particularly useful when a label was created with a type that was Into<SourceSpan> (and had line/col info) and now you want to get that information back from the miette::Diagnostic without doing a bunch of char counting shenanigans).

@zkat
Copy link
Owner

zkat commented Apr 30, 2023

Hiiiii nice to see you around these parts!

So, miette does expose a line/col thing, but it's associated with SpanContents: https://github.com/zkat/miette/blob/main/src/protocol.rs#L252

See also https://github.com/zkat/miette/blob/main/src/protocol.rs#L275

You can even create SourceOffsets using line/col informaron if you want, and use those to create a SpanContents: https://github.com/zkat/miette/blob/main/src/protocol.rs#L454

@MariaSolOs
Copy link
Author

MariaSolOs commented Apr 30, 2023

lol yeah I decided to join the cool kids and use miette 🙈

Okay maybe I should better explain what my issue is. I have error handling code that looks like this:

struct Location {
  // Has line and column info
}

impl From<Location> for miette::SourceSpan { ... }

enum MyError {
  #[error("A bad thing happened")]
  #[diagnostic(code(my_lib::bad_err))]
  BadError(#[label("this is bad")] Location),

  // ...other variants
}

impl MyError {
  /// Gets the line and column info from this error's labels.
  fn locate_labels(&self) -> Vec<Location> {
    // This is where things get ugly.
  }
}

fn report(source_code: String, errors: MyError) {
  for diag in diags {
    println!("{:?}", Report::new(diag).with_source_code(source_code));
  }
}

Basically, I do have a Location type with all the info I want (so the "my location types -> miette types" direction is easy), but then the other direction gets messy. Because I have an enum, I would need to match each variant and extract the Location to get the line and column. I would be able to avoid the huge match if instead a vanilla SourceSpan provided the line and column in some way (because then I could just iterate through self.labels in locate_labels), but of course that doesn't make sense when the diagnostic hasn't been linked with a SourceCode. So maybe it would be a better idea for labels to provide access to the last SpanContents that was computed (?).
Also the only reason I have Location is because of the line and col bits, so it would be nice if I could just use miette's types and get that info from there.

I recognize that this is likely just poor planning/design from my part, but I have seen other projects running into similar issues.

@MariaSolOs
Copy link
Author

MariaSolOs commented May 17, 2023

I'll close this since I found a useful crate that handles location/span mapping :)

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