Try   HackMD

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), nikomatsakis (3), dtolnay (2), joshtriplett (5), Amanieu (6), BurntSushi (8), m-ou-se (2), scottmcm (3)

(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.

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>.

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.

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.

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