[–] 3 points 5 months ago

Wait, what? Any more details about this, I’ve never heard about that before. Partially run Drop impls sounds like a big potential for undefined behavior, how could catch_unwind possibly cause that?

Yeah, no, I don't think this is true. It's the reason a double panic will cause an abort. The docs do recommend against using this for general error recovery, but there's no mention of any possibillity of inconsistent state.

  • source
  • parent
  • context
  • [–] 4 points 5 months ago* (last edited 5 months ago) (1 child)

    catch_unwind [...] does not guarantee the program is in a consistent state afterward, since Drop impls may have run partway through.

    Wait, what? Any more details about this, I've never heard about that before. Partially run Drop impls sounds like a big potential for undefined behavior, how could catch_unwind possibly cause that?

    EDIT: The more I read this article, the more AI-generated it looks and so I'm sort of wondering if the above quote is just complete bogus.

  • source
  • [–] 0 points 5 months ago* (1 child)

    Yes, code golf practiced for any reason other than the sheer joy of it is "stupid." It especially doesn't belong in production code. If typing is really so bad, there are any number of local agents that are competent to finish that map fragment for you.

  • source
  • parent
  • context
  • [–] 0 points 5 months ago (2 children)

    This idea of having to write as little code as possible is stupid.

    Is it? Not only is it less work, but generally makes the code way easier to reason about. In this case, instead of just seeing simple function calls explaining the logic flow, you visually have to parse all this weird extra cruft that is generally irrelevant to what the block is doing.

  • source
  • parent
  • context
  • [–] 3 points 5 months ago (3 children)

    (Didn't read the article.)

    It's not a secret approach or anything. thiserror gives you that with a simple #[from] attribute annotation on the relevant error variant on your Error enum (which is what your Error type should be).

    In your case, this just works because you're not attaching custom context to your error. Usually, you would want to attach some context, and in that case, .map_err()would obviously still be needed, and that's fine. This idea of having to write as little code as possible is stupid.

    Sometimes, attaching context once is sufficient, sometimes it's not. If it's the former, then you can still do From in your bigger error enums which have variants from your smaller error enums (e.g. crate-level Error type with variants trivially wrapping module-level Error types).

  • source
  • parent
  • context
  • [–] [S] 2 points 5 months ago

    "-C", "link-arg=-lstdc++", "-C", "link-arg=-lsupc++", "-C", "link-arg=-lgcc_s"

    good catch!

    rustix - take a look, thx.

    no_std was my deliberate choice. -C prefer-dynamic - it feels that it may be a more fragile option and add some hassles with cross compiling - something like error while loading shared libraries: ... so I have to provide libstd.so as well together with binary to rpi .. where is the gain?

  • source
  • parent
  • context
  • [–] 5 points 5 months ago

    Well, is it really? The verbose part is converting from an error type to another, which you would likely also do in a language with exceptions in the catch block, or in some giant cursed interceptor thing that does a switch/match on the error type (something I had the displeasure to witness with my own two eyes, multiple times)

  • source
  • parent
  • context
  • [–] 13 points 5 months ago* (last edited 5 months ago) (6 children)

    Depending on a usecase you might find that many of your "entrypoint functions" might all share the same error type. For example, if you're making an API backend it's likely gonna be something a status code and a message.

    In that case a simple way to avoid having to pattern match every single error is to implement From<DownstreamErrorType> for MyErrorEnum, and just use the ? operator. Example:

    fn do_something_with_database() -> Result<Whatever, DatabaseError> { /* ... */ }
    
    impl From<DatabaseError> for MyErrorType { /* ... */ }
    
    // this would be your function
    fn api_get_something() -> Result<SomeOtherType, MyErrorType> {
        let data: Whatever = do_something_with_database()?;
        // ...
        Ok(/* ... */)
    }
    

    EDIT: this is mentioned in the article already

  • source
  • parent
  • context
  • [–] 6 points 5 months ago (13 children)

    Rust's explicitness and being forced to handle every case is so incredibly frustrating but also feels so right.

    Thanks for posting this. I'm still trying to figure out the best technique to error handling in my programs. I just learned about anyhow the other day and kind of starting to work that in.

    I'm so tired of having to reshape errors with match statements.

    let result = match foo(a, b) {
       Ok(r) => r,
       Err(err) => {
           return Err(MyErrorEnum::Error(err.to_string()));
       }
    };
    

    This pattern is an annoying habit I keep finding myself repeating.

  • source
  • [–] 5 points 5 months ago (1 child)
        "-C", "link-arg=-lstdc++",
        "-C", "link-arg=-lsupc++",
        "-C", "link-arg=-lgcc_s"
    

    Now, that's just funny. But hey, you're using -Os to keep that binary size low 😇

    And what's with the global allocator being initialized in a module? (didn't/don't know if that even works)

    If you want to do things really minimally, check out the rustix crate which wraps syscalls directly.

    Otherwise, and if loading huge shared libraries is fine, then you might as well not go nostd at all, since you can just pass -C prefer-dynamic for that elusive magically-small std-using binary 🙄

  • source
  • [–] 1 point 5 months ago

    Clap has an entry in their cookbook for a REPL:

    Of course, this works best for simple stuff, where you just have individual commands to parse.

    For a Python-style REPL with a full-fledged language attached, I would not use that approach.
    There's probably some REPL languages implemented in Rust already out there, where you can look at their approach.

  • source
  • [–] 15 points 5 months ago (1 child)

    Shit.

    Glad it had a happy ending (as much as possible anyway). Also very interesting! Especially the bit about it being difficult to getting stuck in a psychiatric hospital.

    I also find it interesting how much it took before they went to the hospital. #merica.

  • source
  • view more: ‹ prev next ›