• INeedMana@piefed.zip
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 day ago

    use core::convert::Infallible;
    fn can_never_fail() -> Result<(), Infallible> {

    Judging by recently discovered use of unwrap this might be a trap for some ;D

    • thingsiplay@beehaw.org
      link
      fedilink
      arrow-up
      1
      ·
      1 day ago

      I don’t understand why this never type was introduced at all. Instead functions not returning, shouldn’t Rust enforce returning from function and instead use a None in place of never type? Otherwise how will the “Unwinding” of program flow implemented?

      • 0xDEADBEEFCAFE@programming.dev
        link
        fedilink
        arrow-up
        7
        ·
        1 day ago

        shouldn’t Rust enforce returning from function

        How do you enforce returning from exit or a function with a loop that never terminates?

      • SorteKanin@feddit.dk
        link
        fedilink
        arrow-up
        6
        ·
        1 day ago

        shouldn’t Rust enforce returning from function

        This is impossible. How would you enforce that? What prevents a function from panicking, aborting the whole process or just going into an infinite loop? All these things correspond to the never type.

        I think you’re misunderstanding what the never type is. It’s not equivalent to None at all. It’s a type that doesn’t have any values. This is useful in situations with generic code where for example an error type can be chosen as the never type. Then you could destructure or unwrap a Result without handling the error, cause the type system guarantees the error never occurs.

        I think you should read up on the never type a bit more. It’s a perfectly natural part of the type system. In fact you can make your own very easily: enum Never {}

      • TehPers@beehaw.org
        link
        fedilink
        English
        arrow-up
        3
        ·
        1 day ago

        I don’t know where None comes from (what’s the T in Option<T>?)

        Assuming you meant (), that’s a unit type with one valid value. It’s a ZST, but can be created and returned.

        ! is a bottom type. It’s uninhabited. Can’t be created. Functions can never return it because they can never construct it. So why’s this useful? It can be coerced to any type.

        Because the set of valid values for ! is the null set, by contradiction, there do not exist any values valid for the type ! that are invalid for any other type T. Therefore, all valid values of ! are also valid values of any other type T, and you can always convert from it to any other type.

        Notably, this is already possible, but language support for it isn’t amazing:

        enum A {}
        
        fn bar(a: A) {
            let foo: Box<Arc<Rc<Mutex<String>>>> = match a {}
        }
        

        Heck you can even do this today:

        // `loop {}` never returns, so its type is `!`:
        let blah: String = loop {};
        
        • thingsiplay@beehaw.org
          link
          fedilink
          arrow-up
          1
          ·
          1 day ago

          To me it makes no sense. Because if it never returns, then it has no return value. Therefore it makes no sense to have a type for something that does not exist.

          • TehPers@beehaw.org
            link
            fedilink
            English
            arrow-up
            5
            ·
            1 day ago

            Because if it never returns, then it has no return value.

            Then how would you annotate having no return value?

            • thingsiplay@beehaw.org
              link
              fedilink
              arrow-up
              1
              arrow-down
              1
              ·
              1 day ago

              I guess it makes sense. What I struggled with is, as the type is unusable basically and I didn’t like the idea it being a type. But for documentation reasons, it makes sense. Otherwise, it has no practical meaning. Even a comment could have the same effect.

              • TehPers@beehaw.org
                link
                fedilink
                English
                arrow-up
                4
                ·
                1 day ago

                The never type comes more from type theory and isn’t common in other languages (though TS has never). Similar to 0 or the null set, it exists as a “base case” for types. For example, where you have unions of T1 | T2 | ..., the “empty union” is the never type. Similarly, for set theory, a union of no sets is the null set, and in algebra, the summation of no numbers is 0.

                In practice, because it can’t be constructed, it can be used in unique ways. These properties happen to be super useful in niche places.

      • kcuf2@lemmynsfw.com
        link
        fedilink
        arrow-up
        1
        arrow-down
        3
        ·
        1 day ago

        It’s because they wanted to hack control flow functionality into expressions. Returning None is actually returning something, but never is just a placeholder for any type when they want to do things that may exit the expression entirely. This is an example in the docs

        let num: u32 = match get_a_number() {
            Some(num) => num,
            None => break,
        };
        

        Break exits the expression without ever producing a value.

        This is an unfortunate wart to appease a desire to those that want to be able to write code like they do in legacy languages. There should have been better ways to do this without being a hack IMO

        • SorteKanin@feddit.dk
          link
          fedilink
          arrow-up
          4
          ·
          edit-2
          1 day ago

          I think you’re misunderstanding the never type. The never type is not a hack at all. It’s a very natural part of the type system. Just as you have the unit type (), which is the canonical type with only 1 value, you also have the never type, the canonical type with 0 values.

          This is extremely useful in generic code. See my other comment in this thread.

          This is an unfortunate wart to appease a desire to those that want to be able to write code like they do in legacy languages

          What do you mean with this? I can’t really decipher it. What alternative to the never type would you want?