---
date: 2025-03-11
url: https://hackmd.io/YbARqJXPRRmkJplWXo4b7A
---
# Libs-API Meeting 2025-03-11
###### tags: `Libs Meetings` `Minutes`
**Meeting Link**: https://meet.jit.si/rust-libs-meeting-crxoz2at8hiccp7b3ixf89qgxfymlbwr
**Attendees**: David, JoshT, Mara, TC
## Agenda
- Time zones suck, daylight "savings" time doubly so
- Triage
- Anything else?
## Triage
### FCPs
10 rust-lang/rust T-libs-api FCPs
- merge rust.tf/80437 *Tracking Issue for `box_into_inner`* - (1 checkboxes left)
- merge rust.tf/106418 *Implement `PartialOrd` and `Ord` for `Discriminant`* - (2 checkboxes left)
- merge rust.tf/130823 *Tracking Issue for `non_null_from_ref`* - (3 checkboxes left)
- merge rust.tf/137280 *stabilize ptr::swap_nonoverlapping in const* - (4 checkboxes left)
- merge rust.tf/115585 *Tracking issue for `cfg_match`* - (4 checkboxes left)
- merge rust.tf/134213 *Stabilize `naked_functions`* - (2 checkboxes left)
- merge rust.tf/136877 *Fix missing const for inherent pointer `replace` methods* - (3 checkboxes left)
- merge rust.tf/137928 *stabilize const_cell* - (3 checkboxes left)
- merge rust.tf/137992 *Stabilise `os_string_pathbuf_leak`* - (4 checkboxes left)
- merge rust.tf/137653 *Deprecate the unstable `concat_idents!`* - (4 checkboxes left)
[tmandry (1)](https://rfcbot.rs/fcp/tmandry), [nikomatsakis (3)](https://rfcbot.rs/fcp/nikomatsakis), [dtolnay (2)](https://rfcbot.rs/fcp/dtolnay), [joshtriplett (5)](https://rfcbot.rs/fcp/joshtriplett), [Amanieu (6)](https://rfcbot.rs/fcp/Amanieu), [BurntSushi (8)](https://rfcbot.rs/fcp/BurntSushi), [m-ou-se (2)](https://rfcbot.rs/fcp/m-ou-se), [scottmcm (3)](https://rfcbot.rs/fcp/scottmcm)
### (nominated) rust.tf/libs358 Update Windows exe search order (phase 2)
Discussed two weeks ago.
New suggestion by Chris: https://github.com/rust-lang/libs-team/issues/358#issuecomment-2683524977
### (nominated) rust.tf/74985 Tracking Issue for slice::array_chunks
Need to figure out what to do with the `N==0` case.
JoshT: Make it a runtime error or compile error depending on if it is const eval'ed?
TC: That's just a regular `assert!()`. In a const context, that will error. Here are the options. The analogy is that `divide` is what we would do for `array_chunks`. The `divide_checked` function is the example of the problem that we're talking about (what people may or may not be able to write usefully).
Option 1: Use a constant assertion.
```rust!
const fn divide<const D: u64>(n: u64) -> u64 {
const { assert!(D > 0) }; // <--- Post-mono assertion.
n / D
}
const fn divide_checked<const D: u64>(n: u64) -> Option<u64> {
match D {
0 => None,
1.. => Some(divide::<D>(n)),
}
}
fn main() {
dbg!({const { divide_checked::<1>(1) }});
dbg!({const { divide_checked::<0>(1) }}); // <--- Look here.
dbg!(divide_checked::<1>(1));
dbg!(divide_checked::<0>(1)); //~ ERROR
}
```
Playground link at: https://github.com/rust-lang/rust/issues/74985#issuecomment-2677242740.
Option 1b: Use a constant assertion and add a compiler feature to error on a generic being provided as a const generic argument to save space for changing the type of the const generic to `const D: NonZero<u64>`.
```rust!
const fn divide<#[require_concrete_val] const D: u64>(n: u64) -> u64 {
const { assert!(D > 0) }; // <--- Post-mono assertion.
n / D
}
const fn divide_checked<const D: u64>(n: u64) -> Option<u64> {
match D {
0 => None,
1.. => Some(divide::<D>(n)), //~ ERROR
}
}
fn main() {
dbg!({const { divide_checked::<1>(1) }}); //~ ERROR
dbg!({const { divide_checked::<0>(1) }}); //~ ERROR
dbg!(divide_checked::<1>(1)); //~ ERROR
dbg!(divide_checked::<0>(1)); //~ ERROR
}
```
Option 2: Use a runtime assertion.
```rust!
const fn divide<const D: u64>(n: u64) -> u64 {
assert!(D > 0); // <--- Runtime assertion.
n / D
}
const fn divide_checked<const D: u64>(n: u64) -> Option<u64> {
match D {
0 => None,
1.. => Some(divide::<D>(n)),
}
}
fn main() {
dbg!({const { divide_checked::<1>(1) }});
dbg!({const { divide_checked::<0>(1) }});
dbg!(divide_checked::<1>(1));
dbg!(divide_checked::<0>(1));
}
```
Option 3 (with arbitrary time delay): Wait for a language feature like `const match` before stabilizing anything.
```rust!
const fn divide<const D: u64>(n: u64) -> u64 {
const { assert!(D > 0) }; // <--- Post-mono assertion.
n / D
}
const fn divide_checked<const D: u64>(n: u64) -> Option<u64> {
const match D { // <-- Doesn't exist yet.
0 => None,
1.. => Some(divide::<D>(n)),
}
}
fn main() {
dbg!({const { divide_checked::<1>(1) }});
dbg!({const { divide_checked::<0>(1) }});
dbg!(divide_checked::<1>(1));
dbg!(divide_checked::<0>(1));
}
```
David: We want this to be usable in an if-branch that's not taken at runtime.
JoshT: So `const { divide::<0>(1) }` will error at compile time, and `divide::<0>(1)` will panic and perhaps lint.
TC: `divide_checked` is not `divide`.
`divide_checked` is the example that should still work.
The 8472: With option 1 a user can use https://github.com/rust-lang/rust/issues/122301 to avoid the post-mono error. But it's clunky and not forward-compatible.
Summary:
- Option 1, const assert, catches errors at compile time but doesn't allow conditionals that avoid calling the function if N == 0.
- Option 2, non-const assert, allows conditionals on N == 0 but doesn't catch errors until runtime.
TC: Straw poll:
- Mara:
- Option 1 would be bad
- Option 2 is acceptable (and consistent with some other things)
- Option 3 would be good
- Josh:
- Option 3 is ideal, once we have the lang feature, but we may not want to wait for it.
- Option 2 would be acceptable with a lint (but is it forward-compatible with 3?)
- Option 1 is preferable over 2, to catch errors at compile time, and for forward compatibility with either 2 or 3
- dtolnay:
- Best: option 2 + dedicated lint
- Like: option 2
- Dislike: option 1, delay for option 3
- 8472:
- Option 1b preferred since it provides more forward-compat for future const-generic improvements and some users have said they only
really need fixed values for chunking. So maybe good enough.
- Option 1 is second choice.
- TC:
- Option 1: This is what I would expect people to write. There's a language limitation here, but it seems fine to me to just lean into that for the moment. I'd expect mostly people are going to write things like `array_chunks::<3>(..)`. Offering this now would provide immediate value. Then the case of passing in a generic can be solved on the lang side later by making language progress.
### (nominated) rust.tf/122661 Change the desugaring of `assert!` for better error output
### (nominated) rust.tf/134446 Stabilize the `cell_update` feature
### (nominated) rust.tf/137198 Rename `cfg_match!` to `cfg_select!`
josh: Would prefer not to rename. `match` is a more familiar name to people and this does work like a match.
### (nominated) rust.tf/137653 Deprecate the unstable `concat_idents!`
### (nominated) rust.tf/137654 Debug impls of ExtractIf have inconsistent trait bounds
### (nominated) rust.tf/137928 stabilize const_cell
### (nominated) rust.tf/138016 Added `Clone` implementation for `ChunkBy`
### (waiting on team) rust.tf/136687 Improve the documentation of `Display` and `FromStr`, and their interactions
### (waiting on team) rust.tf/136912 Add missing trait implementations for ScopedJoinHandle
### (new change proposal) rust.tf/libs558 Use `TEB` to get process information on Windows
### (new change proposal) rust.tf/libs557 Add `iter::Peekable::next_unpeek`
### (new change proposal) rust.tf/libs556 fs::append
josh: Since `File::append` has been approved, this becomes as simple as `File::append("path")?.write_all("hello")?;`. Turning that into a single function doesn't seem worth it.
### (new change proposal) rust.tf/libs555 Add `std::io::Seek` instance for `std::io::Take<T>` when `T: Seek`
### (new change proposal) rust.tf/libs554 Add `std::process::Output::exit_ok`
### (new change proposal) rust.tf/libs553 Add a "shrink-if-excessive" API to `Vec`
### (new change proposal) rust.tf/libs552 Provider-style API for `Context`
### (new change proposal) rust.tf/libs551 ACP: std::os::unix::process::CommandExt::chroot
### (new change proposal) rust.tf/libs550 `impl Display for CStr`
### (new change proposal) rust.tf/libs549 Add `uNN::checked_sub_nonzero`
### (stalled change proposal) rust.tf/libs379 Combine, an iterator adapter which statefully maps multiple input iterations to a single output iteration
### (stalled change proposal) rust.tf/libs111 Restructure ptr_metadata to minimal support
### (stalled change proposal) rust.tf/libs296 ACP: Designing an alternative `FromStr`
### (stalled change proposal) rust.tf/libs333 `NonNull::{from_ref, from_mut}`
### (stalled change proposal) rust.tf/libs369 Implement more `ExactSizeIterators` on 64-bit platforms
### (stalled change proposal) rust.tf/libs287 ACP: Add `FromByteStr` trait with blanket impl `FromStr`
### (stalled change proposal) rust.tf/libs253 Provide way to deconstruct std::iter::Rev
### (stalled change proposal) rust.tf/libs295 Create iterator function in std libs: split_item_mut()
### (stalled change proposal) rust.tf/libs348 std::os::unix::env::{argc, argv}
### (stalled change proposal) rust.tf/libs350 std::slice::from_raw_parts alternative that would accept a null pointer if len == 0 by returning an empty slice
_Generated by [fully-automatic-rust-libs-team-triage-meeting-agenda-generator](https://github.com/rust-lang/libs-team/tree/main/tools/agenda-generator)_