# Meeting 2023-09-27
<!-- Leave your topic starting with ### in the relevant sections below -->
## Critical
<!-- bugs, soundness issues, urgent patches/reviews etc. -->
## Status Reports
Gary is working on the `callsite!()` macro but cannot join this week due to travelling/conference. Will report next week.
<!-- You want to report on something you are working on/request reviews.
Or you want to know the status of something someone else is doing -->
## Discussion Questions
<!-- Anything that requires lengthy discussion/more general questions also fit here -->
### Bindgen C Macro constants
Example from [Fujita's PHY driver](https://lore.kernel.org/rust-for-linux/20230924064902.1339662-2-fujita.tomonori@gmail.com/):
```rust
/// Sets duplex mode.
pub fn set_duplex(&mut self, mode: DuplexMode) {
let phydev = Opaque::get(&self.0);
// SAFETY: This object is initialized by the `from_raw` constructor, so it's valid.
unsafe {
match mode {
DuplexMode::Full => (*phydev).duplex = bindings::DUPLEX_FULL as i32,
DuplexMode::Half => (*phydev).duplex = bindings::DUPLEX_HALF as i32,
DuplexMode::Unknown => (*phydev).duplex = bindings::DUPLEX_UNKNOWN as i32,
}
}
}
```
I dislike the cast `bindings::DUPLEX_FULL as i32`. Bindgen generates
```rust
pub const DUPLEX_FULL: u32 = 1;
```
from the C code
```clike
#define DUPLEX_FULL 0x01
```
But it is always used as an `int` in the C side.
Miguel: I see `__u8` and `unsigned` uses too.
**Question:** is there anything we can do about this?
### Enum <-> Int conversions
Also see [this email](https://lore.kernel.org/rust-for-linux/652520d9-c409-6bb4-821b-5bb8bf99bc0d@proton.me/) and above.
The C code defines the constants like this:
```clike
/* Duplex, half or full. */
#define DUPLEX_HALF 0x00
#define DUPLEX_FULL 0x01
#define DUPLEX_UNKNOWN 0xff
```
In Rust Fujita then defines
```rust
enum DuplexMode {
Full = 0,
Half = 1,
Unknown = 0xff,
}
```
and uses int <-> enum conversions when setting the duplex.
**Questions:**
- can we both avoid `as` casts and still have zero cost conversions?
- do we want the Rust compiler to optimize the enum layout for us?
Gary: For both questions: I don't think we need to avoid `as` casts for enums for now. Given https://github.com/rust-lang/rust/pull/81642 is closed, the current idiomatic way to do this is probably still `as` casts.
*However*, for duplex mode, I think we actually have something like this:
```rust!
#[derive(PartialEq, Eq)]
pub enum Duplex {
Half,
Full
}
impl Duplex {
pub fn to_int(mode: Option<Duplex>) -> i32 {
match mode {
Some(Duplex::Half) => bindings::DUPLEX_HALF,
Some(Duplex::Full) => bindings::DUPLEX_FULL,
None => bindings::DUPLEX_UNKNOWN,
} as _
}
pub fn from_int(num: i32) -> Option<Duplex> {
match num as u32 {
bindings::DUPLEX_HALF => Some(Duplex::Half),
bindings::DUPLEX_FULL => Some(Duplex::Full),
_ => None,
}
}
}
```
I don't think accessing duplex mode is a perf bottleneck and using `None` to represent `Unknown` makes so much more semantic sense.
Miguel: https://github.com/rust-lang/rust-bindgen/issues/2646
Small-meeting consensus: let's discuss in the next meeting again; ask `bindgen` for more features around `enum`s and code generation (e.g. `Option` vs. `Result`, `repr`). `derive(...)` is provided via `--with-derive-custom-enum`.
### `to_result`
Miguel: Should we go with Wedson's & Tomonori's suggestion? Should `to_result` still use `Error::from_errno`? i.e. cap the negative values (outside the `ERR_PTR` case which we do differently).
Wedson: I am not aware of a function that uses very negative values for an actual value. We could have two functions if needed in the future. Should we return `c_uint` in the happy path?
Consensus: Yes to return a value from `to_result`. Yes to keep using `Error::from_errno`. Even if someone makes a mistake, this would be converting the happy path into an error, and thus the mistake should be easy to spot (and there is the `pr_warn` too).
Miguel will send a patch series.
## Miscellaneous
<!-- stuff that does not fit into other categories -->