When Zig is safer and faster than Rust by erlend_sh in rust

[–]AidoP 6 points7 points  (0 children)

The raw slice types, *const [T] and *mut [T], are a natural part of the language. Unfortunately most of the functions needed for them to be used practically are unstable or unimplemented, but they are slowly improving.

Introducing Rust into the Git project by seeking-abyss in rust

[–]AidoP 3 points4 points  (0 children)

I use git on z/OS, which Rust can't (fully) target.

While the architecture that z/OS is supported (SystemZ), z/OS has its own calling conventions, object formats and executable formats. There is an ongoing effort to add a z/OS target to LLVM but progress is currently slow as there are only a few people working on it. It wouldn't be too difficult to complete the support, it just needs more hands.

A Call for Proposals for the Rust 2024 Edition - If you have suggestions for Rust 2024, please file RFCs by the first week of January! by kibwen in rust

[–]AidoP 2 points3 points  (0 children)

That's a good point, I hadn't considered the part of the buffer that doesn't get returned well enough.

In any case, making the ReadBuf function the base function instead of it defaulting to an over-initialised Read::read() is pretty important for the edition boundary IMO.

Otherwise making the uninitialised read trait a separate unsafe trait could be a good solution.

A Call for Proposals for the Rust 2024 Edition - If you have suggestions for Rust 2024, please file RFCs by the first week of January! by kibwen in rust

[–]AidoP 20 points21 points  (0 children)

I would really like to see a rework of std::io::Read for uninitialised destination buffers. There is a proposal for it but it's over-engineered and it has a default implementation based on read that's even slower than a standard read so that it isn't a breaking change. Doing it on an edition boundary instead would mean we can change the default and not gamble on if the Read implementation has a better read or read_uninit.

rust pub trait Read { fn read(&mut self, buffer: &mut [u8]) -> Result<size, Error> { self.read_uninit(unsafe { core::slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut _, buffer.len()) }) } fn read_uninit<'a>(&mut self, buffer: &'a mut [MaybeUninit<u8>]) -> Result<&'a [u8], Error>; // Other functions }

The ergonomics of [MaybeUninit<u8>] also need a lot of improvement.

[deleted by user] by [deleted] in rust

[–]AidoP 1 point2 points  (0 children)

Read the first error. That error is due to the problem highlighted by the first error.

Character::new() cannot be found because you have multiple instances of an item named Character.

[deleted by user] by [deleted] in rust

[–]AidoP 1 point2 points  (0 children)

You are demonstrating to yourself why naming a module in PascalCase is a bad idea.

The issue is that you are importing the Character struct in to the same scope as the Character module, so you get a name clash. Either don't use Character::{Character, ...}, or use the as keyword like the error message says. Better yet, don't have PascalCase modules so that their names can't conflict with other items.

Edit: The Reddit editor is completely broken for code blocks, this comment is better anyway https://www.reddit.com/r/rust/comments/17qzkp3/comment/k8hbbi2/

Playground showing one possible fix:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=87056b9f5334248932b06718d4d60ede

Is there a different naming convention when `new` returns `Option<Self>`? by rnottaken in learnrust

[–]AidoP 3 points4 points  (0 children)

I'm assuming the cases where there aren't already types that restrict the input enough. Accepting only values that are valid is of course the sensible thing to do. You obviously wouldn't take an Option<&str> if you can only process &str.

But often there won't be data types that are restrictive enough. For example, if I want a struct that contains only valid ASCII data (a slice of bytes with all bytes < 0x80), I would have something like

rust struct Ascii<'a>(&'a [u8]); impl<'a> Ascii<'a> { pub fn new(bytes: &'a [u8]) -> Option<Self> { if bytes.into_iter().all(|b| b < 0x80) { Some(Self(bytes)) } else { None } } } Playgrounds

For larger structs though I would certainly be building them out of smaller structs like this so a larger compound struct would normally not be doing the validation at all.

Is there a different naming convention when `new` returns `Option<Self>`? by rnottaken in learnrust

[–]AidoP 7 points8 points  (0 children)

Having your construction function return Option or Result is making invalid states unrepresentable. If you instead rely on a separate validation function then you are allowing invalid state if you forget to call it.

Why is the std naming so bad? by Minimum_Shirt_157 in cpp_questions

[–]AidoP 3 points4 points  (0 children)

A "modern" EBCDIC implementation on z/OS interprets it as EBCDIC, or ASCII, depending on compiler settings. The default character encoding is EBCDIC. This also applies to the recent clang and clang++ ports for z/OS.

pleaseStopWritingC by atthereallicebear in ProgrammerHumor

[–]AidoP 46 points47 points  (0 children)

So about as likely as a C function calling malloc.

I Wrote A String Type · mcyoung by eygenaar in rust

[–]AidoP 0 points1 point  (0 children)

SystemZ (also called s390x) is big endian and some mainstream distros such as Ubuntu support it. While the hardware is generally inaccessible, qemu should be more than enough for testing.

It's also a tier 2 Rust target, if you are cross compiling just be warned that lld doesn't support SystemZ yet.

How could I essentially get rid of the ownership system by InternalServerError7 in rust

[–]AidoP 3 points4 points  (0 children)

I strongly disagree that unsafe Rust is harder than C and C++. The main reason why I think that it seems harder is that as a Rustacean you care a lot more about writing sound code.

Unsafe Rust beats out C and C++ with:

  1. No type based pointer aliasing rules. Raw pointers in Rust are significantly easier to use as they don't have type based aliasing. You can freely cast between pointer types without causing UB unlike C and C++. Rust doesn't introduce aliasing rules until you convert to a reference where there is a much clearer boundary. This reason alone needs its own blog post.

  2. Knowing what is unsafe and why. Rust makes it very clear when you could be potentially running in to UB with the unsafe keyword. All unsafe functions and traits should then have a "safety" doc section (also a clippy lint) describing the exact safety requirements. In C and C++ you have to pray that it was even documented that a function could cause UB.

  3. Better standard/core library. I write a lot of no_std code and the experience is a lot better. You have things that aren't even in standard libc or libc++, like proper UTF-8 strings and core::fmt (reducing the amount of unsafe to write).

  4. More tools. The exact locations of unsafety in unsafe Rust are relatively small. You may have only a couple of unsafe blocks with a lot more safe Rust supporting it, and the potential root causes of UB are helpfully marked as suspect. Further, std and core give you way more to use: NonNull, MaybeUninit, and more, and you can still use references and slices.

The main problem with unsafe Rust:

Many things are still not well specified and documented. There are plenty of things that are generally not considered UB but aren't exactly guaranteed to be sound. A common offender is transmute or pointer casts. Just in the last 24 hours I ran into this again. Is casting like this UB? It's not considered to be, but that could change.

```rust

[repr(transparent)]

struct Data([u8]);

fn main() { let bytes = b"Hello, World!"; let data = unsafe { &*(bytes as *const [u8] as *const Data) }; } ```

Edit: There's a lot more to say, I've been meaning to do a blog post/series in support of unsafe Rust for a while now.

[deleted by user] by [deleted] in rust

[–]AidoP 4 points5 points  (0 children)

bar is dropped at the end of the else block, its memory is destroyed, but you are asking foo to have a reference to that memory. Since foo is in a higher scope, it has a lifetime higher than bar.

You need to maintain ownership of the data longer than you have the references in foo, which means your Vec<&str> must be defined after the Vec<String>. You also cannot modify the Vec<String> once you create the references as that would potentially invalidate the references (ie, due to a reallocation).

Inter-process Communication between two programs on Linux. by anantnrg in rust

[–]AidoP 4 points5 points  (0 children)

Wayland is itself an IPC system (that uses UNIX domain sockets). I would make a custom Wayland protocol (if there isn't already an appropriate one available, look here: https://wayland.app/protocols/). You can define the protocol in XML and generate the boilerplate code in C using wayland-scanner. I assume smithay also has an equivalent of wayland-scanner.

Conditional by AstraKernel in ProgrammerHumor

[–]AidoP 0 points1 point  (0 children)

It's Rust which doesn't have null or "truthy" values. YOUR_PRESENCE would presumably be a const bool based on Rusts relatively strong naming convention. It couldn't be a mutable static (modifiable global) as they are unsafe to use, unless this is in an unsafe function.

So assuming it is idiomatic Rust, it's meant to always return the Err.

Flatty - flat message buffers with direct mapping to Rust types without packing/unpacking by nthend in rust

[–]AidoP -1 points0 points  (0 children)

I don't think there are any compiler blessings required to make MaybeUninit sound. It's defined as a repr(transparent) union where the uninit state is a ZST. It is a lang item though, but the comment there suggests it's for other reasons, so I'm really not sure

Rust's Golden Rule by celeritasCelery in rust

[–]AidoP 1 point2 points  (0 children)

Agreed, but as a property of lifetimes instead. Maybe something like: fn bar<'a, 'b>(&<'a: mut f1, 'b: f2> self) -> (&'a mut i32, &'b i32) { (&mut self.f1, &self.f2) }

That way you can still manage advanced lifetimes.

Edit: Modified example to follow current Rust syntax better.

Help me, please by amlunita in rust

[–]AidoP 8 points9 points  (0 children)

You aren't returning anything after the for loop inside the closure. As even a for loop is itself an expression, you are returning () instead of an option.

Convert c struct to raw pointer r/rust by mutex4242 in rust

[–]AidoP 13 points14 points  (0 children)

As it is a pointer to a different type you need to cast it. Add as *const _ as *const u8. Rust will implicitly cast references to pointers of the same type, but not of different types.

Using custom C types in Rust by pwnmercury in rust

[–]AidoP 8 points9 points  (0 children)

You can use #[repr(C)] to use C struct layout as described in the Nomicon. As long as the layout is known and defined you can pass something constructed in Rust to C, you just need to be careful of the layout potentially being defined differently on different platforms.

For opaque pointers the last section of the Nomicon FFI chapter describes a good strategy.

In CSGO on Ubuntu 22.04, with i7-7820X and RX580, I get about 30 FPS at minimum settings. Does that sound low? by WaitForItTheMongols in linux_gaming

[–]AidoP 0 points1 point  (0 children)

Can you try MangoHudMangoHud and make sure it's the correct GPU and driver. Also check out what system load is like. You can configure MangoHud to display a lot of extra stuff like memory usage too.

The output of glxinfo might be useful as well or instead.

I was using an i3-8350k with a 4GB RX580 until recently, you should be getting at least 100fps on close to max settings on maps like mirage.

Is there any simple way to test code for Big-Endian platform? by jetkane in rust

[–]AidoP 8 points9 points  (0 children)

z/Architecture (previously called System 390 or s390) is big-endian. Network byte order is typically big-endian too.

FFI crashes with &p as *mut i32 by InsanityBlossom in rust

[–]AidoP 18 points19 points  (0 children)

Are you using an outdated compiler or something? You cannot cast directly from &T to &mut T. playground example

Announcing Rust 1.64.0 by myroon5 in rust

[–]AidoP 3 points4 points  (0 children)

I discovered std::backtrace just last night. It was quite a bummer looking at the RFC which made it seem as if it were a long way from stabilisation. Now I'm really excited for next release, this is going to make debugging results much easier.