You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
2922: tock-register-interface: replace register tests by const assertions r=phil-levis a=lschuermann
### Pull Request Overview
This replaces the automatically generated tests for register structs defined through the `register_structs!` macro by static assertions evaluated at compile time.
This has some significant advantages over the current approach:
- errors in the struct offsets and violation of other invariants is detected immediately on compilation and not only when running tests. This increases developer ergonomics significantly and reduces the potential for errors and weird behavior at runtime.
- the crate no longer generates tests which rely on the standard library being present in the users' code. While the library itself still has tests which rely on the presence of the standard library, these tests are for internal validation only. In `no_std` environments, relying on the standard library even just for `#[test]` functions can be problematic. For developers, the choice has been to either use the standard library and have test, implement a workaround to provide the standard library when running tests but not otherwise, or not generate the tests at all. These changes enable us to make the library purely `#[no_std]` compatible and not impose any standard library requirements on user code.
It does not come without drawbacks though. Because Rust's const panic features, especially w.r.t. string formatting, are still very limited, the provided debug information is significantly reduced. For instance, it as of now seems impossible to interpolate any const variable content into the assertion message. This is likely to be resolved in the future, when Rust allows more elaborate string formatting techniques at compile time. As an additional consequence, the assertions code is less readable.
The generated error messages are quite prominent during the compilation process and easy to identify:
error[E0080]: evaluation of constant value failed
--> chips/lowrisc/src/uart.rs:16:1
|
16 | / register_structs! {
17 | | pub UartRegisters {
18 | | (0x00 => intr_state: ReadWrite<u32>),
19 | | (0x04 => intr_enable: ReadWrite<u32>),
... |
41 | | }
42 | | }
| |_^ the evaluated program panicked at 'Invalid end offset for field val (expected 49 but actual value differs)', chips/lowrisc/src/uart.rs:16:1
### Testing Strategy
This pull request was tested by compiling.
### TODO or Help Wanted
- [x] Remove the `std_unit_tests` feature and only make the standard library available when the crate itself is tested.
- [x] Update the README.md documentation.
### Documentation Updated
- [x] Updated the relevant files in `/docs`, or no updates are required.
### Formatting
- [X] Ran `make prepush`.
2933: Have Grant::each() take FnMut instead of Fn r=phil-levis a=hudson-ayers
### Pull Request Overview
This restriction is a holdover from when all of the Grant functions took Fn closures, but there is no longer any reason to limit the functionality of the closures passed to this method.
### Testing Strategy
This pull request was tested by compiling the following closure:
```rust
let mut next = Ticks64::max_value();
self.apps.each(|_, app, kernel_data| {
if let Some(deadline) = app.expiration {
// We don't have to worry about rollover comparisons with 64-bit ms timer
if deadline <= now {
// Schedule callback and remove this expiration
let _ = kernel_data.schedule_upcall(Sub::Fired as usize, (0, 0, 0));
app.expiration = None;
} else {
next = next.min(deadline);
}
}
});
```
which only compiles if each() accepts FnMut closures.
### TODO or Help Wanted
N/A
### Documentation Updated
- [x] No updates are required.
### Formatting
- [x] Ran `make prepush`.
Co-authored-by: Leon Schuermann <leon@is.currently.online>
Co-authored-by: Hudson Ayers <hudsonayers@google.com>
0 commit comments