zkat / miette

Fancy extension for std::error::Error with pretty, detailed diagnostic printing.
https://docs.rs/miette
Apache License 2.0
1.85k stars 106 forks source link

`#[label]` derive doesn't seem to work with `Option<T>` where `T` implements `Into<SourceSpan>` but not `Copy` #377

Open cdisselkoen opened 1 month ago

cdisselkoen commented 1 month ago

The Diagnostic derive fails in the following:

use miette::{Diagnostic, SourceCode, SourceSpan};
use thiserror::Error;

#[derive(Debug, Clone)]
pub struct MySpan {
    span: SourceSpan,
    src: String,
}

impl From<MySpan> for SourceSpan {
    fn from(value: MySpan) -> Self {
        value.span
    }
}

impl From<&MySpan> for SourceSpan {
    fn from(value: &MySpan) -> Self {
        value.span
    }
}

impl SourceCode for MySpan {
    fn read_span<'a>(
            &'a self,
            span: &SourceSpan,
            context_lines_before: usize,
            context_lines_after: usize,
        ) -> Result<Box<dyn miette::SpanContents<'a> + 'a>, miette::MietteError> {
        self.src.read_span(span, context_lines_before, context_lines_after)
    }
}

#[derive(Debug, Clone, Error, Diagnostic)]
#[error("it didn't work: {details}")]
pub struct MyError {
    details: String,
    #[help]
    help: Option<String>,
    #[label("here's the problem")]
    span: Option<MySpan>,
}

The error message is "cannot move out of a shared reference" and says the problem is that Option<MySpan> does not implement Copy.

The derive works fine for span: MySpan, just not for span: Option<MySpan>.