GithubHelp home page GithubHelp logo

Comments (3)

erratic-pattern avatar erratic-pattern commented on June 16, 2024

I'm not convinced this is the intuitive behavior. I would expect with_source_code to override any existing source code that was given prior, via the derive macro or otherwise. I think it would be more confusing for the user if with_source_code didn't override the source code, and it would make it impossible to use this feature in cases where you do want to override it.

I'm also not sure how this could be implemented, due to the type erasure of boxing the Diagnostic. You could downcast, but you would need to know the specific concrete type, not just "some type that implements Diagnostic".

Maybe a separate helper method for this behavior would be better? Assuming there's some way to fetch the existing source code (which I'm not sure there is currently). It could be named to make it clear that it's only adding source code if missing.

--EDIT--

You can get the behavior you want by checking for existing source code conditionally.

Example:

#[test]
fn miette_two_source_codes() -> miette::Result<()> {
    #[derive(thiserror::Error, miette::Diagnostic, Debug, Clone, PartialEq)]
    #[error("error")]
    struct E {
        #[label("here")]
        at: miette::SourceSpan,
        #[source_code]
        source_code: String,
    }
    let source1 = "source1";
    let source2 = "source2";
    // create report with source1
    let report = miette::Report::from(E {
        at: (4..5).into(),
        source_code: source1.to_string(),
    });
    // shadow previous variable (or you can use mut instead)
    let report = match report.source_code() {
        None => report.with_source_code(source2),
        _ => report,
    };
    Err(report)
}

I think this is more clear because it makes the behavior explicit, whereas implicitly and silently ignoring with_source_code when a source code is already provided would be more confusing IMO.

from miette.

gavrilikhin-d avatar gavrilikhin-d commented on June 16, 2024

I'm not convinced this is the intuitive behavior.
I would expect with_source_code to override any existing source code

It's hard for me to name a single use-case for changing source code without changing any locations.

from miette.

gavrilikhin-d avatar gavrilikhin-d commented on June 16, 2024

Here is a real-life example when I need non-overriding Report::with_source_code:

  1. There is a TypeMismatch error for passing arguments of incorrect type to function.
    Function declaration, of course, may be located in a different file than a function call
/// Diagnostic for not convertible types
#[derive(Error, Debug, Clone, PartialEq)]
#[error("expected `{expected}` type, got `{got}`")]
pub struct TypeMismatch {
    /// Expected type
    pub expected: TypeWithSpan,
    /// Real type
    pub got: TypeWithSpan,
}

impl Diagnostic for TypeMismatch {
    fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
        Some(Box::new("semantics::type_mismatch"))
    }

    fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
        Some(Box::new(
            vec![
                &self.expected as &dyn Diagnostic,
                &self.got as &dyn Diagnostic,
            ]
            .into_iter(),
        ))
    }
}
  1. TypeWithSpan stores a SourceFile or None, if it's located in the current file.
#[derive(Error, Diagnostic, Debug, Clone, PartialEq)]
#[error("{ty}")]
pub struct TypeWithSpan {
    /// Type to show
    pub ty: Type,

    /// Span of the thing with the type
    #[label("this has `{ty}` type")]
    pub at: SourceSpan,

    /// Source code of the module, this type is located at
    #[source_code]
    pub source_file: Option<SourceFile>,
}

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

from miette.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.