Re: [TECH TOPIC] Rust for Linux

Andy Lutomirski
2021-07-08T16:07:45Z

> On Jul 8, 2021, at 7:34 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> ﻿Hi Miguel,
>
>> On Thu, Jul 8, 2021 at 4:28 PM Miguel Ojeda
>> <miguel.ojeda.sandonis@gmail.com> wrote:
>>> On Thu, Jul 8, 2021 at 4:18 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>>> Let's assume the caller access a member of the object regardless.
>>> What happens?
>>
>> That is the key: they cannot access it to begin with because the
>> returned `Option` is empty, so there is not even an object you can
>> "access", thus asking "what happens?" does not have a meaning.
>>
>> In code:
>>
>> pub fn f(weak: Weak<i32>) {
>> let strong = weak.upgrade();
>>
>> if let Some(content) = strong {
>> println!("{}", content);
>> }
>>
>> // There is no `content` here, so you cannot do anything with it
>
> What if I would ignore that? I.e.
>
> let Some(content) = strong;
> println!("{}", content);
>
> ?

That won’t compile. Pattern matching like this is fundamentally a
conditional operation. In Rust, or in pretty much any language with
proper “sum types” if you try to “destructure” something (the value
‘strong’ here) and there’s a possibility that the pattern doesn’t
match, then the compiler will require that you have some sort of
appropriate condition.

Personally, for some types of programming, I find sum types by
themselves to be an even bigger win than Rust-style safety. C has
unions, which are painful to use. Python has various hacks that are
unpleasant. C++ likes to pretend that std::variant is decent, but it’s
really quite moderate. Rust, Haskell, etc all have very nice sum
types.

As the most basic example, C often uses a null pointer to mean
“nothing here”, but you’re on your own to remember not to reference a
null pointer. In Rust a reference can’t be null, and Option can be
used to mean “maybe something here, maybe not”. You can’t even
attempt to dereference the pointer without checking if it’s present.

For a more interesting example, a pointer to a page table entry could
be arranged to be a union of:

Empty: nothing there, but still has several bits of usable data
NextTable: a pointer to the next level of page tables
Page: a pointer to the physical address of the data along with access
rights and such

And one could manipulate page tables with no fear of forgetting about
the existence of huge pages — if you try to write code that
misinterprets a huge page (Page) as a pointer to the next table down
(NextLevel), the language won’t let you.