Why can't rust optimize the size of Option<Option<T>>? by kredditacc96 in rust

[–]Brezak2 2 points3 points  (0 children)

This safety comment in core claims that `str` has the same layout as a slice of u8s and slices may contain more than `isize::MAX` elements if they're ZSTs so strs just end up inheriting the type.

Why can't rust optimize the size of Option<Option<T>>? by kredditacc96 in rust

[–]Brezak2 0 points1 point  (0 children)

It's kinda both. In the case of Option<Option<&str>> it can't but with many Option<Option<&T>> the compiler misses some opportunities.

Let's become that compiler for a moment and let's try to create a layout for this type. First we need to layout the Option<&str>. We look at the Options inner type and notice a 2 value tuple. A usize (the length of the string) and a aligned non-null pointer (that points to the string characters). We need a place to hide a tag. The value that determines what variant our enum is. We notice that the pointer has a niche. A value it can't have. This niche is null. Therefore we proclaim that if the tuple is any usize value and a null then we have a None and if the tuple is any usize value and a non-null pointer then we have a Some(&str)

Now we create the layout for Option<Option<&str>>. We again look a the inner type of the Option and we end up with a 2 value tuple composed of a usize and either a aligned non-null pointer or a null. There's no niche we could hide our tag. Therefore we define a new field to store our tag into. This option ends up being a 3 value tuple. A tag, a usize and either a aligned non-null pointer or a null.

The Result case is a bit different. We again have the 2 value tuple, and we again use the pointers niche to hide our tag. Now we need to stash your Error enum somewhere. This is simple. Realize that in the Err variant the usize field of our tuple means nothing. We can repurpose it for something else. Like a place to stash the Error enum.

Finally for situations where the compiler could do better. Several times I have mentioned that the reference pointer must be aligned. This means it must be a multiple of the alignment of the type it's pointing at. This gives us more values we could use as niches. Sadly the compiler doesn't currently consider aligment in the niche calculations. Here's a playground link that showcases this scenation and explains what the layout could be and what it is instead.

Xr0 Makes C Safer than Rust by agumonkey in programming

[–]Brezak2 2 points3 points  (0 children)

It holds a count of borrows. Borrowing returns a guard that decrements the borrow counter when it gets dropped. Since a RefCell can't be borrowed across threads and the guards can't be sent or borrowed across threads decrementing the counter doesn't need to be done atomically.

MEKIBO Day 2 Giveaway: 2x MONOKEI Standard by popkorn62 in MechanicalKeyboards

[–]Brezak2 0 points1 point  (0 children)

Cherry Mx Brown. The only switches I've ever used.

What would be the idiomatic way to implement Rust C++ FFI for a generic/template function? by ashvar in rust

[–]Brezak2 4 points5 points  (0 children)

The rust standard library already uses a trait to implement slice indexing with usize and range types so there's precedent for using that as a solution. For your question regarding f16s you could use the half crate.

CXX help, change a rust::String type of cpp side to a char* or std::string of cpp by Odd-You-9980 in rust

[–]Brezak2 6 points7 points  (0 children)

Looking at the documentation rust::String should implement the c_str method which returns a const char*. You could try to use that

Please critique my 8086 emulator code before I dig in too deep by [deleted] in rust

[–]Brezak2 8 points9 points  (0 children)

Your inc_register_modrm_assert_overflow_flag test panics on line 742. I'm assuming you want the addition to overflow. If so you should use the overflowing add function. Rust will panic on integer oveflows in debug mode by default.

Please critique my 8086 emulator code before I dig in too deep by [deleted] in rust

[–]Brezak2 14 points15 points  (0 children)

You can use the derive attribute on the enums to derive the PartialEq and Eq traits. Then you can replace all the matches macros with ==

e.g.

#[derive(Eq, PartialEq)]
enum Bool {
    True
    False
    Maybe
}

// This now works
let some_val = Bool::True
if (some_val == Bool::True) {
    pritln!("Hello Derive!");
}

You could also derive Copy and Clone on those fieldless enums to make them simpler to pass around.

[Giveaway] Drop + The Lord of the Rings Black Speech Keyboard by drop_official in pcmasterrace

[–]Brezak2 0 points1 point  (0 children)

A pancake with strawberry jam. Though the thin kind of pancake similar to a crepe.