---
# System prepended metadata

title: Libs-API Meeting 2025-06-17
tags: [Minutes, Libs Meetings]

---

```
title: Libs-API Meeting 2025-06-17
tags: ["T-libs", "triage-meeting", "minutes"]
date: 2025-06-17
url: https://hackmd.io/AMASFx8oRn-JNL4TPp04hw
```
# Libs-API Meeting 2025-06-17

###### tags: `Libs Meetings` `Minutes`

**Meeting Link**: https://meet.jit.si/rust-libs-meeting-crxoz2at8hiccp7b3ixf89qgxfymlbwr
**Attendees**: Amanieu, David, JoshT, Mara, The 8472, Chris Denton, martinomburajr, Tomas Sedovic, TC

## Agenda

- Triage
- Anything else?

## Triage

### FCPs

1 rust-lang/rfcs T-libs-api FCPs

  - merge rust.tf/rfc3809 *RFC: enable \`derive(From)\` for single\-field structs* - (5 checkboxes left)

12 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/140881 *Tracking Issue for duration\_constructors\_lite* - (3 checkboxes left)
  - merge rust.tf/139087 *Fallback \`{float}\` to \`f32\` when \`f32: From\<{float}\>\` and add \`impl From\<f16\> for f32\`* - (6 checkboxes left)
  - merge rust.tf/129333 *Tracking Issue for \`lazy\_get\`* - (3 checkboxes left)
  - merge rust.tf/138879 *Ensure non\-empty buffers for large vectored I/O* - (3 checkboxes left)
  - merge rust.tf/141840 *If \`HOME\` is empty, use the fallback instead* - (3 checkboxes left)
  - merge rust.tf/127213 *Tracking Issue for AVX512\_FP16 intrinsics* - (3 checkboxes left)
  - merge rust.tf/136306 *Tracking Issue for NEON fp16 intrinsics* - (3 checkboxes left)
  - merge rust.tf/141520 *Tracking Issue for const {OsString, PathBuf}::new* - (3 checkboxes left)
  - merge rust.tf/141996 *Fix \`proc\_macro::Ident\`'s handling of \`$crate\`* - (3 checkboxes left)
  - merge rust.tf/70530 *Tracking Issue for {BTreeMap,BTreeSet}::extract\_if* - (3 checkboxes left)

[dtolnay (1)](https://rfcbot.rs/fcp/dtolnay), [nikomatsakis (3)](https://rfcbot.rs/fcp/nikomatsakis), [joshtriplett (9)](https://rfcbot.rs/fcp/joshtriplett), [the8472 (1)](https://rfcbot.rs/fcp/the8472), [tmandry (1)](https://rfcbot.rs/fcp/tmandry), [compiler-errors (1)](https://rfcbot.rs/fcp/compiler-errors), [BurntSushi (9)](https://rfcbot.rs/fcp/BurntSushi), [scottmcm (2)](https://rfcbot.rs/fcp/scottmcm), [Amanieu (4)](https://rfcbot.rs/fcp/Amanieu), [m-ou-se (9)](https://rfcbot.rs/fcp/m-ou-se), [jackh726 (1)](https://rfcbot.rs/fcp/jackh726)

### (nominated) rust.tf/130703 *Tracking Issue for secure random data generation in \`std\`*

Amanieu: On me. Need to write down the notes from the meeting we had last week.

### (nominated) rust.tf/135178 *Document the behaviour of RUST\_MIN\_STACK=0*

Amanieu: What the author of the PR thought was happening is not what's happening. The docs are wrong. So things our confusing, but our behaviour right now is not consistent across platform.

Amanieu: On Linux 0 is ignored. On Windows it's set to the default stack size (1MB). On ESP-IDF it treats 0 as ??. We could make it so if you set stack size to 0 we'll set it to the platform default. It just feels that we're using this value of 0 instead of a proper switch to set the native stack size.

Josh: Environment variables are stringly typed so we could say "we take a number but you can also specify `default`".

The 8472: Considering it's not platform consistent, I'm not sure that talking about people's expectations makes much sense here.

Chris: It's definitely a number that sets the stack size above zero.

The 8472: We have no platform where `0` tries to set it to zero.

Amanieu: The doc for stack size says that the actual number can be higher if the platform specifies a minimum stack size.

Amanieu: Do we want to change the behaviour? Document something? Right now it says "if you set it to zero, it's going to round up to the platform minimum".

The 8472: That's what we do on Linux but on window is it the minimum?

Josh: On Windows you can set it to a lower value, right?

*people trying to figure out the minimum size on Windows*

Amanieu: The minimum size on Windows is 1 page plus the guard page plus the stack guranatee. Technically we could calculate it manually but in practice we don't want to do that.

Chris: For panic handling it also uses a large number.

Amanieu: I'm inclined to leave it unspecified.

Amanieu: Could we say: "setting the stack size below platform minimum, will result in platform specific behaviour which may be a minimum stack size or something else the platform defines".



### (nominated) rust.tf/141994 *add Iterator::contains*

David: We have an accepted FCP from 12 months ago. This breaks the itertools code. We're waiting for shadowing.

TC: We've accepted on the lang side; I don't know any blockers for stabilization.

Amanieu: Adding `Iterator::contains` doesn't break anything.

David: Do you know why we had to change rust-analyzer?

Amanieu: In theory the rust-analyzer change is not needed if it's not enabling the Iter::Contains nightly

David: I will investigate.

David: The signatures of itertools vs. this are different. It could be that the code in rust-analyzer will break when we stabilize this.

Amanieu: If it's just a warning this is acceptable. If it's a hard breakage, it'll be an issue.

TC: Looking at the code I can't imagine why it'd cause breakage on just nightly.

*Amanieu looking at logs*

Amanieu: "Error: a method of this name may be added to the Rust in the future" future-compat warning. Because rust-analyzer is denying warnings.

David: Maybe the fix is to allow "future-compat" to rust-analyzer.

TC: I'd say this is ok since if they're denying warnings, they're asking for breakage.

Amanieu: Ok.

### (nominated) rust.tf/142325 *Stabilize the \`breakpoint\` function*

(Ongoing discussion about specifying semantics.)

Josh: The FCP got derailed by the discussion on the lang side that's ongoing that's taking place asynchronously.

TC: I nominated it on the libs-api side based on the lang discussion, for awareness. The bulk of our sentiment was to treat it as an implementation quality issue of doing what Josh is suggesting here. On the lang side, we need to specify the behavior more precisely, and in particular, decide whether a no-op or unconditional abort is an acceptable implementation.

Amanieu: We could avoid this by documenting which instruction this will be emitted that.

Josh: That's already what the documentation says for some platform. The main issue is more about what the specification would say about this instruction. Which part's guaranteed and which part isn't.

TC: It says what instruction is produced currently but it doesn't guarantee what instruction will be produced.

Mara: After that the lang discussion turned onto why is this function safe.

Amanieu: A trapping specification is safe.

Mara: Yes but that gets us to having to specify this. Do we generate the code after the trap? Is it safe that the code can continue after the trap instruction?

Josh: This discussion is getting into what the behavior would be on the Rust abstract machine.

TC: The other thing that came up is that you want this instruction to emit a compiler fence. Therefore it emits an observable effect. Meaning even if this turns into a nop you still want a compiler fence.

Mara: That's the same for every inline assembly.

Amanieu: With the default flags, yes.

TC: Conceivably, a workflow here is that you have some code, and you put a breakpoint in the middle (so you want the remaining code to still be emitted, and you're expecting it to be able to run through the breakpoint). Since it's going to emit that compiler fence, you'd want to pass a compiler flag that causes it to emit a no-op (with the compiler fence) to test and confirm the fence doesn't affect the behavior. Then you could turn off that flag and proceed with debugging.

Mara: If it's that sensitive, don't modify the program at all. Set the breakpoint from your debugger.

The 8472: You could set a static value that's exported. The assembly would read from it and skip the trap if it's set. That way you could config the behaviour. Since the compiler can't looked at the assembly, it won't know whether it could skip the code or not.

Mara: If you're working on a heisenbug you don't want to modify the program to observe it.

Josh: I'd expect to use this, for instance, in situations where the code runs for 20 minutes. In that case I'd put it in an `if`. 

The 8472: Can we just make a noop function that's __rust_breakpoint and the debugger can set a Rust entry breakpoint that doesn't modify code?

Mara: Yes, but this is about providing a way to insert the existing arch instruction without having to write inline assembly.

TC: The lang team is open to this as long as they figure out how to specify it and get a consenses on how exactly this will work.

Mara: Sounds like we need to wait for the spec discussion, then.

Josh: The breakpoint intrinsic doesn't use inline assembly, it uses LLVM's intrinsic. Unclear if emitting an LLVM trap implies emitting a compiler fence

Amanieu: It depends on what attributes you put on the call instruction. By default it does treat it as a compiler fence.

TC: We'll probably want to write that down in the documentation.

Mara: I don't think we have a definition of what a compiler fence means from a semantics (opsem) perspective yet.

Amanieu: This should mean what an FFI call means.

The 8472: The unsafe code guidelines issue has been resolved.

TC: We have a `std::sync::atomic::compiler_fence` that takes an `Ordering`.

Mara: I don't think that's the right thing to use.

Amanieu: It just treats it as an FFI call.

Chris: Do we need to do anything else in this meeting? This needs lang/spec to resolve it.

### (nominated) rust.tf/142579 *Use raw pointer for NUL\-terminated file location with \`#\[track\_caller\]\`*

> There is still a plan to make `&CStr` a thin pointer that does not know the string length.

Josh: Should this still be the plan? For many years we've carefully limited what we add to `CStr`/`CString`, but it's still the case that making them thin pointers will likely impose costs on many programs, invoking `strlen` many times. Would it make sense to have a `ThinCStr`?

Mara: It'd reduce the number of strlen calls in plenty of programs..

Mara: Regardless, I don't see any case where we want to use a raw pointer for this. Even if we don't make &CStr thin, we'd have another type to represent a thin C string pointer.

Amanieu: Does anyone remember if panic location is passed by value or reference.

Mara: By reference I think.

Josh: I don't think this is a question of size. If it's a CStr it may require a `strlen` call.

Amanieu: It's initialized as a constant, including the length.

Mara: Today we don't use any strlen for Location. This PR adds calls to strlen for Location::file().

Amanieu: This PR also adds an api function that produces a Cstr than 

Josh: You're right, Mara. I'm not sure why this change was proposed if it's *introducing* a new strlen operation.

The 8472: The common use will be returning a Rust string anyway. Can we store the Rust string, terminate with a null byte. And if you need a cstr, just send the pointer to the rust string.

Mara: We're doing that anyway. I don't see the point of this PR. It uses a worse type (raw pointer which isn't even a `Send` or `Sync`), and _adds_ strlen calls for the regular (non-CStr) call.

The 8472: The argument here is creating a Cstr requires knowing a length. 

Mara: But if we come from Rust we already know the length. 

Amanieu: This doesn't introduce any new calls. But if we want to combine this with #117431 which actually changes 

https://github.com/rust-lang/rust/pull/117431

Amanieu: This is always used in the slow path.

Mara: Even if we did make Location not store the length (*and* we don't make &CStr thing), it's still fine because the compiler can optimize away the strlen call if you don't use the length.

Josh: Sounds like there isn't even a strlen call because we know the length.

Amanieu: Agreed, looks like we'll reject it.

Mara to respond.

### (waiting on team) rust.tf/139087 *Fallback \`{float}\` to \`f32\` when \`f32: From\<{float}\>\` and add \`impl From\<f16\> for f32\`*

waiting on lang, not libs.

### (waiting on team) rust.tf/141996 *Fix \`proc\_macro::Ident\`'s handling of \`$crate\`*

Amanieu: This is waiting on lang.

TC: This is towards the top of lang queue. It's for our awareness, and so we can review the great write-up by David.

### (new change proposal) rust.tf/libs606 *ACP: Add methods for converting bool to \`Result\<(), E\>\`*

The 8472: Didn't we reject something similar recently?

*no one recalls that*

Josh: Equivalent for what `then_some` does for `Option`.

Amanieu: The naming's bad because `then_err` shouldn't take a closure. Could be `.else` but `else` is a keyword.

Josh: If we want consistency, `bool::then` takes a closure and `bool::then_some` doesn't take a closure but a value. That would imply `.then_err` should take a value.

TC: The obvious but bad name is `.then_result`.

Mara: Seems a bit weird to have a function specifically for `Result<()>`.

Amanieu: Colud we just add `ok_or` and `ok_or_else` to `bool`?

Mara: We could but then you'd start treating `bool` as an `Option<()>`. Not entirely unfair, but meh.

Mara: I don't think there's that many usecases to add this.

Amanieu: The motivated usecases link shows a lot.

Josh: Seems like a common pattern.

Mara: Interesting, that's more than I expected. I wouldn't object to adding this as an unstable.

TC: Is there something we could add to concisely turn it into an `Option<()>` or `Result<(), ()>`?

Mara: We have that today with `then_some` and then convert it to a `Result`.

TC: What I mean is, we already have all the needed combinators on `Option` and `Result`; is it enough to have a concise way to "lift" the `bool` into both an `Option` and `Result` (and in the case of `Option`, do so more concisely than `.then_some(())`)?

Amanieu: The most concise possible thing would be `bool::opt` and that still doesn't look great.

The 8472: I think what people want is method chaining and you can't do that with if-else. Postfix macros would help here.

Mara: I wouldn't object to adding this to boolean.

### (new change proposal) rust.tf/libs605 *impl \`AsRef\<\[T; N\]\>\` and \`AsMut\<\[T; N\]\>\` for \`\[T; N\]\`*

### (new change proposal) rust.tf/libs604 *Implement (non\-short\-circuiting) \`Sum\` for \`Saturating\<\_\>\`*

### (new change proposal) rust.tf/libs603 *A \`Static\` receiver type for dyn\-trait methods that do not take values*

### (new change proposal) rust.tf/libs602 *ACP: add \`array::from\_raw\_parts()\`*

The 8472: The author says feel free to close as this can be all done with pointer and `read` methods.

Josh: It does seem like a mild improvement in terms of clarity, but if you don't want to add it and tell people to use pointer cast then so be it.

The 8472: I wouldn't call it `from_raw_parts` -- it copying the value not constructing it from a reference.

TC: What about just `from_raw`?

The 8472: They're proposing multiple methods. One is reading a value, another is providing an array from a pointer. That could be called `from_raw_parts`. Or `from_pointer`. `Core::array::from_ptr`

Josh: Should we close this since it can be done with pointer manipulation or accept?

Amanieu: "parts" being plural feels weird.

The 8472: We could name it differently. On the pointer type we could have a method that could read n values instead of a single one.

Amanieu: I think these methonds should be on pointer types rather than on array types. If we want them at all.

The 8472: There are 2 proposals: The first is to read an array from a pointer. The other is constructing an array reference from a raw pointer. They could be named differently, have different signatures, live in different places.

Amanieu: It seems to me that this is just `.cast().read()` and ??

TC: Trying to figure out if this is safer.

The 8472: `cast` does type inference for you on both the type and array length. This fixes the type.

TC: Yes, so it constrains it.

Chris: Could this just be a clippy lint that says if you want the cast, you should specify the type?

The 8472: There seems to be a lot of untyped casts in the compiler. If we add a lint, that would probably trigger a lot of work.

TC: This makes sense to me if we come up with good names. If these existed, would I reach for them? Yes, I probably would.

Josh: I probably wouldn't reach for these. This is just barely making it any nicer than the raw pointer cast.

*discussion about whether this is to support converting between types too: the problem statement talks about `[T; N]` to `[U; N]` but the solution sketch only talks about a single type*

Josh: We should ask about the discrepancy in the problem statement.

TC: The thing that makes sense to me is what's in the solution sketch where it constraints the `T`.

Josh: The problem statement is the part that would be much more interesting to me.

The 8472: I'll ask for clarification.


### (new change proposal) rust.tf/libs601 *ACP: Safe conversions between arrays and \`std::arch\` vector register types*

Amanieu: Unclear whether it's the job of the standard library to provide these. We don't some generic from impl. Instead we'd like a safe version of intrinsics. E.g. `from_pointer` taking a reference of an array. But at that point it becomes a high-level API on top of `std::arch` and inclear if that's std's job to provide this.

Josh: I appreciate the point of us not wanting to provide stable SIMD implementation. But this particular case: there are two ways to do this. You could use an unsafe operation, do the operation, store them back. But you should be able to a safe SIMD where you load, do an operation, store. And if the only thing stopping you from doing that safely is the load and store then it makes sense.

Amanieu: Load and Store we already have stable. By using regular Rust move.

Josh: If I have an array of bytes and I want to write a SIMD algorithm and only using safe intrinsics, the only unsafe code I'm writing is turning a `[u8]` into a `u32`.

Amanieu: Agreed there's value but I don't think that's the job of the standard library to provide that.

The 8472: Can we provide these on a platfor-by-platform bases only on platform where it's ambiguous? Where there's no endiannes confusion?

Josh: Is it actually ambiguous on ARM 

Josh: If we're only using the common ones that are safe to use?

Amanieu: That way you'd end up mirroring the entire load api from intrisics.

Josh: Yes, that's what I'd like.

Amanieu: I don't think that belongs in the standard library. There's a lot of potential API design that comes into play. I'd feel much more comfortable if this was an external crate that provides a wrapper over the base intrinsics in std::arch.

Josh: If this were created in the ecosystem, iterated on and settled, would you feel different about including it into the standard library?

Amanieu: I would feel different then.

Josh: I don't agree that this doesn't belong in the standard library but I agree the standard library is not the place to experiment on this.

Josh: Does it seem sensible to tell them to experiment on this in the ecosystem and then come back here?

Amanieu: Yes.

The 8472: That's what portable-simd is, isn't it?

Josh: This is a much smaller surface that may get it in at some point in a way that portable-simd likely never will. I'm suggesting implementing some specific load/store methods on standard library types possibly via extension traits. The `u8` case is pretty trivial, it's the `u16`, `u32`, `u64` types where it can get trickier.

Josh will write this up.

### (new change proposal) rust.tf/libs589 *\`ptr::fn\_code\_ptr\` for explicitly getting an opaque pointer of a function*

### (new change proposal) rust.tf/libs587 *ACP: \`try\_exact\_div\` method on \`NonZero\<{integer}\>\`*

### (new change proposal) rust.tf/libs578 *ACP: hash\_map! macro to create \`HashMap\`s such as \`vec!\`*

### (new change proposal) rust.tf/libs577 *Option::try\_get\_or\_insert\_with*


### (stalled change proposal) rust.tf/libs191 *Add LocalWaker support*

### (stalled change proposal) rust.tf/libs253 *Provide way to deconstruct std::iter::Rev*

Josh: Asks for a method that gives you the inner iterator back out. This seems reasonable. Not widely used but seems trivial to either make the field public or providing `into_inner` method.

TC: Agreed.

Josh: Prefer the `into_inner` method.

TC: I feel adding `into_inner` is the right thing to do.

Josh: That way we don't have to make any guarantees about the exact layout.

TC: +1

Josh: The alternatives section mentions an into_inner downside for a `&mut` iterator. The proposal suggests `as_inner_mut`. 0 objetions to this.

TC: I'd probably do both at once. Surprising we haven't had to do that anywhere else.

The 8472: `into_inner` is less problematic than `as_inner_mut`. If you do any transformation of the inner type, if it's reversible we can do it to `into_inner`. Not if we have mutable references.

Josh: If we're considering `as_inner_mut` we may as well just have the field public. At that point you can do everything you want with it as if it were public.

TC: It's hard to imagine why making the field public would end up being a problem.

The 8472: Specializations may use having exclusive access to the inner type. `Rev` doesn't implement the `SourceIter` specialization trait so that should be ok.

TC: What is that?

The 8472: It's used for in-place iteration. Gives the iteration temporary access to the inner type. Has assumption on who can access the inner iterator. `StepBy` transforms the inner iterator and we can't return it afterwards. So for some adaptors we have constraints that don't allow us to hand out the inner one.

Josh: How do we want to handle this?

The 8472: We can make it public but it'll limit our future options to provide optimizations. So I'd prefer `into_inner`.

The 8472: Let's say you have a linked list. You could swap start and end and get a reverse. We could undo this for `into_inner` but not for `as_inner_mut`.

TC: Wondering when do you actually need to call `into_inner` here? A mutable reference to an iterator is still an iterator. Can't you reverse that reference?

The 8472: The user wanted `Clone` which doesn't work with a mutable reference. They do have a workaround so this isn't necessary. A nice to have maybe?

*agreement on using `into_inner` rather than the whole field*

*The 8472 will reply.*

### (stalled change proposal) rust.tf/libs111 *Restructure ptr\_metadata to minimal support*

### (stalled change proposal) rust.tf/libs255 *Adding \`set\_route\` to \`sys::unix::net\`*

The 8472: Do we allow these CFPs? They'd have to be separate extension trait for each OS.

Josh: Yeah.

Amanieu: The PR was closed, the FreeBSD thinks this is out scope for the standard library.

Josh: Then we should take that as a clear indication that we shouldn't be doing that. We should close the FCP.

Amanieu: Yep.

*The 8472 will comment on the FCP.*

### (stalled change proposal) rust.tf/libs296 *ACP: Designing an alternative \`FromStr\`*

### (stalled change proposal) rust.tf/libs452 *ACP: Implement \`TryFromIterator\<T\>\` trait to compliment \`FromIterator\<T\>\` trait.*

### (stalled change proposal) rust.tf/libs202 *Support for non\-blocking and best\-effort zero\-copy \`io::copy\`*

### (stalled change proposal) rust.tf/libs460 *ACP: \`Stdin::next\_line\` and \`BufRead::next\_line\`*

Josh: Effectively reading a lingle line from `Stdin` or `BufRead` and reading it into a `String` that's allocated for you. `read_line` is more efficient in a loop, but this can be more convenient for single input.

Chris: Seems to make more sense on `BufRead` maybe?

Amanieu: Makes sense for both.

The 8472:`Stdin` is already buffered I think?

Amanieu: Yes.

Josh: Seems like the correct API on the correct type. Do we actually want to provide this given that people might misuse it? We could lint on using in a loop.

The 8472: They also propose a different behaviour in handling new lines (including or not including `\n`).

Josh: They're claiming it's the same behaviour as the `lines` iterator.

The 8472: I was looking at `read_line`. So we already have two different things.

Josh: we could do the same behaviour as `.lines().next().transpose()` but they're proposing that we could 

Josh: Inclination to add this but send a heads-up to the clippy folks for lints about using it in a loop and repeating allocations?

The 8472: Could we instead have a `read_line` on a String that clears the string. You could say: `String::new().read_line(Stdio)`.

Josh: Is that additional complexity worth the saving of the allocation? Because at that point you avoid calling a `clear`.

The 8472: And you can write it on a single line.

Josh: The FCP makes the point that interactive programs are bottle-necked on the human. And so it makes sense there.

The 8472: Prompting a human is something that probably happens more on in the beginner programs but as you're processing date you'll run into the efficiency issues.

Josh: *shrug* either one is an improvement -- which one should we do?

Amanieu: Do we still need this if we add something like `inputln!` macro was proposed?

Josh: The input macro did actually have a solution for both "read it into my buffer" and "read it into an allocated string" cases.

Josh: We can close this and say `input_line` will provide this and cc the folks working on `inputln`.

*Josh will reply to this*

The 8472: Note `inputln` was attempted several times and never made it.

Josh: True but there are folks that are actively pushing it. I don't think it's stalled because no one wants it, more because people don't have time.

*closed with a message*

### (stalled change proposal) rust.tf/libs287 *ACP: Add \`FromByteStr\` trait with blanket impl \`FromStr\`*

### (stalled change proposal) rust.tf/libs195 *OS\-level \`thread::Builder\` priority and affinity extensions*


_Generated by [fully-automatic-rust-libs-team-triage-meeting-agenda-generator](https://github.com/rust-lang/libs-team/tree/main/tools/agenda-generator)_

