miette
miette copied to clipboard
Merge labels from another diagnostic
Sometimes, I want to construct a bigger error from several related ones. It happens either from convenience reasons, or from technical ones (part of the error may be located in another file)
There is an example from my code:
/// Show type in diagnostic
#[derive(Error, Diagnostic, Debug, Clone, PartialEq)]
#[error("{ty}")]
pub struct TypeWithSpan {
/// Type to show
pub ty: Type,
/// Span of expected type
#[label("this has `{ty}` type")]
pub at: SourceSpan,
// TODO: change to `Option<SourceFile>`
/// Source code of the module, this type is located at
#[source_code]
pub source_code: Option<String>,
}
/// Diagnostic for not convertible types
#[derive(Error, Diagnostic, Debug, Clone, PartialEq)]
#[error("expected `{expected}` type, got `{got}`")]
#[diagnostic(code(semantics::type_mismatch))]
pub struct TypeMismatch {
/// Expected type
pub expected: TypeWithSpan,
/// Real type
pub got: TypeWithSpan,
}
Declaration of type and its usage may be splited in different files, so there should be two errors. However, logically it's a single TypeMismatch
error.
I could use:
#[related]
errors: Vec<TypeWithSpan>
But this will decrease type safety, as I know beforehand that this error consist from exactly two errors.
Hence I propose syntax like this to merge labels from another diagnostics:
#[derive(Error, Diagnostic, Debug, Clone, PartialEq)]
#[error("expected `{expected}` type, got `{got}`")]
#[diagnostic(code(semantics::type_mismatch))]
pub struct TypeMismatch {
#[related] // or #[labels]
pub expected: TypeWithSpan,
#[related] // or #[labels]
pub got: TypeWithSpan,
}