Comment by mietek

10 months ago

Your charitable reading is too charitable. One of the benefits of using types to help guarantee properties of programs (e.g. invariants) is that types do not get out of sync with the code, because they are part of the code, unlike documentation. The language implementation (e.g. the compiler) automatically checks that the types continue to match the rest of the code, in order to catch problems as early as possible.

I'm not a kernel developer, and never done anything of the sorts either. But, I think the argument is that if they have two versions of something (the C version + the Rust bindings), the logic/behavior/"semantics" of the C version would need to be encoded into the Rust types, and if a C-only developer changes the C version only, how are they supposed to proceed with updating the Rust bindings if they don't want to write Rust?

At least that's my understanding from the outside, someone please do correct me if wrong.

  • That was a large part of the disagreement.

    Rust developers were saying it would be their job to do this. But then someone said Linus rejected something because it broke Rust. GKH backed the Rust developers and said that was an exception not a rule, but didn't know Linus' stance for sure.

    Then Linus chimes in because of one of Hector's replies, but at the time of my reading did not clarify what his actual stance is here.

  • > how are they supposed to proceed with updating the Rust bindings if they don't want to write Rust?

    If I've interpreted it correctly (and probably not, given the arguments), Linus won't accept merge requests if they break the Rust code, so the maintainer would need to reach out to the Rust for Linux (or someone else) to fix it if they didn't want to themselves.

    And some lead maintainers don't want to have to do that, so said no Rust in their subsystem.

  • Which is a moot point because the agreement right now is that Rust code is allowed to break, so the C developer in question can just ignore Rust, and a Rust person will take care of it for them.

    • As of today, the burden is uncertain and the Rust crowd has not been fixing things quickly enough since they are manual fixes:

      https://lore.kernel.org/rust-for-linux/20250131135421.GO5556...

      > Then I think we need a clear statement from Linus how he will be working. If he is build testing rust or not.

      > Without that I don't think the Rust team should be saying "any changes on the C side rests entirely on the Rust side's shoulders".

      > It is clearly not the process if Linus is build testing rust and rejecting PRs that fail to build.

      For clarity, tree-wide fixes for C in the kernel are automated via Coccinelle. Coccinelle for Rust is constantly unstable and broken which is why manual fixes are required. Does this help to explain the burden that C developers are facing because of Rust and how it is in addition to their existing workloads?

      1 reply →

    • > Which is a moot point because the agreement right now is that Rust code is allowed to break, so the C developer in question can just ignore Rust

      So then the argument that even semantics encoded in the Rust types, can be out of the date compared to the actual code, is actually a real thing? I read that somewhere else here in the comments, but didn't understand how the types could ever be out-of-date, but this would explain that argument.

      2 replies →

Yes, but generic code complicates the picture. The things I saw were like: The documentation says you need a number but actually all you need is for the + operator to be defined. So if your interface only accepts numbers it is unnecessarily restrictive.

Conversely some codepath might use * but that is not in the interface, so your generic code works for numbers but fails for other types that should work.

  • > Yes, but generic code complicates the picture. The things I saw were like: The documentation says you need a number but actually all you need is for the + operator to be defined. So if your interface only accepts numbers it is unnecessarily restrictive.

    if you really need a number, why not use a type specifically aligned to that (something like f32|f64|i32|i64 etc...) instead of relying on + operator definition?

    > Conversely some codepath might use * but that is not in the interface, so your generic code works for numbers but fails for other types that should work.

    do we agree that if it's not in the interface you are not supposed to use it? conversely if you want to use it, the interface has to be extended?

    • Yes, the second case is a bug in the interface.

      For the first case you have it the wrong way around. My generic code would work on things that are not numbers but I prevent you from calling it because I didn't anticipate that there would be things you can add that are not numbers. (Better example: require an array when you really only need an iterable).