miette icon indicating copy to clipboard operation
miette copied to clipboard

Bad span pointing when single line span supersets a prior span

Open CAD97 opened this issue 2 years ago • 3 comments

Excerpt:

use miette::{Diagnostic, ErrReport, Result, SourceSpan};
use thiserror::Error;

#[derive(Debug, Error, Diagnostic)]
#[diagnostic(severity(warning))]
pub enum Warning {
    #[error("invalid target directive specified")]
    #[diagnostic(code(tracing_filter::simple::Warning::InvalidTarget), url(docsrs))]
    InvalidTarget {
        #[label("this `=` is not allowed ...")]
        equals: SourceSpan,
        #[label("... in this target directive")]
        target: SourceSpan,
    },
}

pub fn main() -> Result<()> {
    Err(ErrReport::from(Warning::InvalidTarget {
        equals: (5..6).into(),
        target: (0..12).into(),
    })
    .with_source_code("crate=target=warn"))
}
Error: tracing_filter::simple::Warning::InvalidTarget (link)

  ⚠ invalid target directive specified
   ╭────
 1 │ crate=target=warn
   · ──────┬─────
   ·       │╰── this `=` is not allowed ...
   ·       ╰── ... in this target directive
   ╰────

image

This is, admittedly, a rather degenerate case. But the span is clearly pointing not at the desired location.

If the point is after the halfway point, it works:

Error: tracing_filter::simple::Warning::InvalidTarget (link)

  ⚠ invalid target directive specified
   ╭────
 1 │ xxxxxxxxxxxxxxxxxxxxxxxxxxxx=xx=warn
   · ───────────────┬───────────────
   ·                │            ╰── this `=` is not allowed ...
   ·                ╰── ... in this target directive
   ╰────

image

but if the point is before the halfway point, it gets shoved "out of the way" of the latter span's stem, arbitrarily far from where it's supposed to point:

Error: tracing_filter::simple::Warning::InvalidTarget (link)

  ⚠ invalid target directive specified
   ╭────
 1 │ xx=xxxxxxxxxxxxxxxxxxxxxxxxxxxx=warn
   · ───────────────┬───────────────
   ·                │╰── this `=` is not allowed ...
   ·                ╰── ... in this target directive
   ╰────

image

CAD97 avatar Mar 18 '22 01:03 CAD97

tbh while it's weird, I'm inclined to mark this as "wontfix". When I was writing this, I intentionally decided not to bother making them overlap because I assumed it would make the rendering logic way too complicated and/or the errors not very readable/helpful. Like, what's the "correct" way to display this? I don't know! Anything I can come up with is awful and I think this is a "don't give miette overlapping spans" sort of thing tbh.

zkat avatar Mar 19 '22 00:03 zkat

I could've sworn that rustc emitted errors with a large superset span in some cases, but I can't figure out when it occurs or find an example. Specifically, I feel like I've seen:

   ╭─[1:1]
 1 │
 2 │ ╭─▶︎ 123456789
 3 │ │   123456789
   · │     ──┬─
   · │       ╰── inner span
 4 │ ├─▶︎ 123456789
   · ╰──── outer span
   ╰────

(GitHub's ▶︎ is slightly more than a cell wide... and I event applied the text presentation selector to remove the emoji presentation default)

The lines for this case don't have to overlap, but miette still chokes rather interestingly. The above is cleaned, and what miette actually gave is completely broken:

   ╭─[1:1]
 1 │
 2 │ ╭─▶︎ 123456789
 3 │ │╭▶︎ 123456789
   · ││    ──┬─
   · ││      ╰── inner span
 4 │ ├─▶︎ 123456789
   · ╰──── outer span
   ╰────

image

I'll rethink the structure of these warnings to avoid overlapping the spans, then.

(I think my ideal warning would be smth like

Warning: tracing_filter::simple::Warning::InvalidDirective

  ⚠ invalid directive specified
   ╭────
 1 │ crate=target=warn
   ·      ┬      ┬
   ·      ╰──────┴─── only one `=` is allowed
   ╰────

)

CAD97 avatar Mar 19 '22 02:03 CAD97

The last bug highlighted here (with the two arrow lines in the gutter) is fixed with #316

jdonszelmann avatar Nov 09 '23 23:11 jdonszelmann