# Libs-API Meeting 2026-04-14
###### tags: `Libs Meetings` `Minutes`
**Meeting Link**: https://meet.jit.si/rust-libs-meeting-crxoz2at8hiccp7b3ixf89qgxfymlbwr
**Attendees**: Nia Espera, Chris Denton, Amanieu, David Tolnay, The 8472, Josh Triplett, Tomas Sedovic, Dijana
## Agenda
- Triage
- Anything else?
## Triage
### FCPs
20 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/116258 *Tracking Issue for explicit\-endian String::from\_utf16* - (1 checkboxes left)
- merge rust.tf/98407 *Tracking Issue for \`Exclusive\`* - (0 checkboxes left)
- merge rust.tf/140808 *Implement Default for &Option* - (1 checkboxes left)
- merge rust.tf/141994 *add Iterator::contains* - (1 checkboxes left)
- merge rust.tf/76314 *Tracking Issue for atomic\_from\_mut* - (1 checkboxes left)
- merge rust.tf/151379 *Stabilize \`VecDeque::truncate\_front\`* - (3 checkboxes left)
- merge rust.tf/149926 *Do not deduplicate captured args while expanding \`format\_args!\`* - (1 checkboxes left)
- merge rust.tf/111688 *Tracking Issue for ExitCodeExt on Windows* - (3 checkboxes left)
- merge rust.tf/109737 *Tracking Issue for \`once\_cell\_try\`* - (3 checkboxes left)
- merge rust.tf/121641 *Tracking Issue for \`OnceCell/Lock::get\_mut\_or\_init\`* - (3 checkboxes left)
- merge rust.tf/134021 *Implement \`IntoIterator\` for \`\[&\[mut\]\] Box\<\[T; N\], A\>\`* - (3 checkboxes left)
- merge rust.tf/153261 *Partially stabilize \`ptr\_alignment\_type\` as \`alignment\_type\`* - (3 checkboxes left)
- merge rust.tf/142748 *Tracking Issue for producing a \`Result\<(), E\>\` from a \`bool\`* - (3 checkboxes left)
- merge rust.tf/138215 *Tracking Issue for integer formatting into a fixed\-size buffer* - (3 checkboxes left)
- merge rust.tf/153990 *Decide and document where stdarch intrinsics are allowed to diverge from asm behavior* - (4 checkboxes left)
- merge rust.tf/126769 *Tracking Issue for \`substr\_range\` and related methods* - (3 checkboxes left)
- merge rust.tf/136327 *Tracking Issue for \`unsafe\_cell\_access\`* - (4 checkboxes left)
- merge rust.tf/149219 *Allow shortening lifetime in CoerceUnsized for &mut* - (4 checkboxes left)
[nikomatsakis (1)](https://rfcbot.rs/fcp/nikomatsakis), [the8472 (13)](https://rfcbot.rs/fcp/the8472), [oli-obk (1)](https://rfcbot.rs/fcp/oli-obk), [scottmcm (1)](https://rfcbot.rs/fcp/scottmcm), [dtolnay (3)](https://rfcbot.rs/fcp/dtolnay), [lcnr (1)](https://rfcbot.rs/fcp/lcnr), [spastorino (1)](https://rfcbot.rs/fcp/spastorino), [BurntSushi (12)](https://rfcbot.rs/fcp/BurntSushi), [Amanieu (2)](https://rfcbot.rs/fcp/Amanieu), [joshtriplett (11)](https://rfcbot.rs/fcp/joshtriplett), [BoxyUwU (1)](https://rfcbot.rs/fcp/BoxyUwU)
### (nominated) rust.tf/82766 *Tracking Issue for map\_try\_insert*
Nia: It was nominated again. Trevor Gross summarised the discussion here: https://github.com/rust-lang/rust/issues/82766#issuecomment-4209552699
Nia: Was anyone here involved in the conversation?
Amanieu: I remember we had objections about the try_insert name. There was a discussion about adding fallible versions.
Josh: That's our porblem with fallible collections: it could either mean fallible collection or one to allow what's ??
The 8472: Or it could mean "insert if not exist"
Amanieu: I'm against adding fallible methods on hashmap other than `try_reserve` and `try_shrink`
The 8472: I'd propose `insert_if_not_exist`
Josh: Ah, this doesn't override the existing value. It's not about the construction cost.
The 8472: Yes.
Josh: The conflict between "is it already there" and "can this function fail" would still apply if we never add fallible. But I agree with Aamnieu to add a whole set of fallible functions to `Vec`. I'd still like to have them but under something like `.as_fallible_vec()` and have them under a separate type.
Nia: I agree. But we can still have that and not use the term `try` here. If we stabilise this as `map_try_insert` it'll sound like "this is a fallible allocation".
The 8472: I don't think everything "try" is related to allocation. We can have `Box::try` which is based on the fallibility of the function.
Josh: We have precedence in the standardl library for both meanings of try (this takes a closure with a result, this might fail or fallible allocation).
The 8472: Or non-blocking stuff like `try_wait`
Nia: I'd vote against anythnig with the word "try" in the name
The 8472: Agreed.
David: One of the really good naming convention in the go standrad library is "must". E.g. in regex, it must compile or it will return an error. I wonder if we could adopt something like `must_insert` where if it didn't insert, you'd handle that.
Josh: That's similar to methods like "strict" where it must succeed or panic.
David: It gives a good intuition when reading the code is what the intention is and what you're handling.
Amanieu: The `insert` method should have had the semantics of `try_insert` and we should have a separate method `replace` that does what `insert` does right now. But that ship has sailed.
Nia: I'd go `insert_new`
Amanieu: `insert_unique`
The 8472: `insert_empty`
Josh: `insert_vacant`
The 8472: `Entry` has vacant
Nia: Then I'm leaning towards `insert_vacant`. And people like it (it has most thumbs-up)
Josh: This isn't just on entry, this appears to be directly on `HashMap` and `BTreeMap`.
Nia: "vacant" is hard to misread as anything other than this.
Josh: +1
The 8472: Java has `putIfAbsent`
Josh: There's another reading I could imagine: insert a vacant slot that's ready for me to put things in. You could pass it a key and it would return an `Entry`. You'd know it's not that from the signature but it suggests the name is not perfect.
The 8472: What are the current proposals?
Nia: `try_insert`, `insert_vacant`, `insert_new`.
The 8472: We could have separate names for `Entry` and the collection itself
Nia: Doesn't sound intuitive but we could do that.
The 8472: Entry has the vocabulary with vacant, hashmap does't
David: Then we could just use the entry API: `entry().insert_vacant()`
Josh: That would not be nice for the common use-case. I'd be tempted to call it `add` but there's conflict with the ops
Nia: If yo uwant to go that route, "push"?
Josh: doesn't imply "insert if it's not already there"
Josh: Insert_vacant and insert_new both sound fine. What's ambiguity with `insert_new`?
The 8472: On FileCreationOptions we have `create_new` that only creates the file if it doesn't exist
Nia: Okay, that's precedent.
Nia: There are other points discussed. We could let this cook and look at the other things. And then we can see if there's more of a consensus.
Nia: Do we want to kep the `Error + Display for OccupiedError` implementation? I'd still keep it.
Amanieu: Agreed.
Nia: I don't see why it would ever be a problem if we allow it.
The 8472: Conditionally on the value we ipmlement it for, right?
Nia: Yes.
The 8472: Yes, nice for printing.
Nia: Is everyone in agreement?
The 8472: Do we have other cases? Where data parsing fails? Could this be an accidental data leakage problem? If other error types already implement `Display` for data, then it's fine.
Nia: I'll take a look.
The 8472: Just doing logging at the call-site would already print stuff.
Nia: But if you're doing that, you'd understand that's what you're doing. You're printing the value.
The 8472: You don't automatically see what the error's printing.
Nia: I guess that's not necessarily obvious that it would do that. We could add that to the unresolved questions. There's another possibility that the `Error` impl doesn't hold anything, it's just a set string.
The 8472: A lot of other errors are like that. E.g. integer parsing errors just say that you e.g. couldn't parse the string, not containting the actual value.
Nia: We could remove the impls for `Display + Error` but keep `Debug`. And then bring them back if needed.
Nia: Do we have tentative agreement on removing `Display` and `Error`?
The 8472: The purpose is you try to get the value and put it back in?
Nia: Yes.
Josh: The `OccupiedError` in the error place would point to the value you provided?
Nia: It has the `Entry` (so the key and original value) and the value you tried to provide.
Josh: +1 for removing `Display`. What was the rationale for removing `Error`?
Amanieu: `Error` requires `Display`
Josh: Right. I regularly forget that `Error` requires `Display` and not just `Debug`.
The 8472: We could have `Display` return a fixed string
Nia: If it's a fixed string we'd have to hold to a lifetime.
The 8472: We could have a tuple that holds the ErrorKind and then the other value that ??
Nia: Either way, this sounds like something we'd have to design. I think it makse sense to remove the imypls for now and we can bikeshed the design for later.
Nia: Next, do we want public fields or accessor methods? I generaly prefer the fields opaque so accessor methods.
The 8472: If it's `non_exhaustive` you also coan't construct it so it'd solve the problem too.
Nia: Fair. But I generally favour accessors if we want to change the implementation later?
The 8472: What's our UTF8Error?
Nia: IT has a private field with accessor methods
Amanieu: In this case I think it's fine for all the fields to be public. There's no additional information we'd add. And it's simpler.
Nia: It's fine but I field weird letting it be easily constructed. We could put `non_exhaustive` on it. Do we have an agrement on public fields and non_exhaustive?
Amanieu: Yes.
Nia: The last thing is should it contain the `K` that was attempted the insert?
Amanieu: Sure, I see no downside. It's passed as an argument anyway. It comes in, it comes back out.
The 8472: Didn't we debate something similar (a shape of an error that should be a tuple of things) recently?
Nia: Is everyone okay with this?
Amanieu: I'm happy with it.
Nia: Let's tentatively say yes.
Nia: Back to the name bikeshed.
Amanieu: I prefer `try_insert`
Nia: Why?
Amanieu: It tries to insert. It's all in the name.
Josh: In the absence of ever using "try" for anything else I'd agree. The only obvious issue would be the ambiguity of what's it trying. It's not a closure. Given the constraints, this is the only thing it could mean?
Amanieu: This is also the first name that will come to people's minds when they try to type this.
Nia: True.
Josh: If we were to decide we want to not do fallible allocation as a parallel set of "try_" methods and add a method to toggle between the two later, would we deprecated `try_reserve` then?
Amanieu: No because `try_reserve` would eb much more convenient.
Josh: Would we document that?
Amanieu: I don't think we need to.
Josh: "try" has the inconsistency.
The 8472: The user shouldn't assume it's bound to a specific failure reason because "try" it can mean so many different things.
Nia: That sounds to me like an argument against "try_insert". Because of the ambiguity.
The 8472: When you use the autocomplete, you'll see that it's fauling due to the occupied error and not allocation.
Josh: I'm coming around to `try_insert`
Amanieu: Yes it'll cause some ambiguity but better than calling it something else. I expect `try_insert` to be called much more often than all the other try methods.
The 8472: With autocomplete typing `try_` would only suggest "insert" after typing all that, taking up a lot of characters to type
Josh: If we do this, then the consistency is "it does what the non-try corresponding method does, but it can fail. And the failure depends on the how the function could fail". That seems like a good consistency to have.
Nia: That's a very strong case.
Josh: I think we should stop considering the fallible allocation case as the only/main meaning for "try". And open the possibilities to us.
Nia: That's convincing to me. What does everyone else think?
Nia: There is the possibility of `checked_insert`. That's how we do it for the number types. Where something could overflow. This is "checking whether the slot is already taken". But unless someone loves that I'm happy with "try".
Amanieu: I think "try" is better than "checked". That if this fails, no insertion happens.
Nia: Summary: cut out `Error` and `Display`, add the `K`, cut out the accessors, add `non_exhaustive`. And `try_insert`
Nia: I'll type out the reply.
### (nominated) rust.tf/127544 *Tracking issue for CommandExt::show\_window*
Amanieu: There's a request for stabilization. I nominated it and I'd like Chris to give feedback. IT's a windows thing.
Chris: That looks fine to me.
The 8472: The values you're passing tehre are stable constants?
Amanieu: The Windows API takes an int.
Chris: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa
Nia: There are probably invalid u16s you can pass there?
Chris: Yes, at the moment it's an enum
Amanieu: Should this be a non-exhaustive enum?
Nia: Yes. `u16` feels weird because it's not a number here.
Chris: Generally we do the minimum we need here.
Josh: I'd caution againts passing an enum as we'd replicate the Windows enum here and we'd have two definition of it: one here and the other in Windows.
Nia: I don't like it but if that's how we do that here, then sure
Chris: If you look at an OpenOptionsExt we have the same thing there.
The 8472: The're not Rust options, they're windows options.
Amanieu: Should this have a `StartupInfo` prefix? We have other `StartupInfo` structs there
Chris: They're different in that they're flags
Josh: This seems fine to me.
Nia: Yes, let's just stabilize it then. Should we open an FCP?
Amanieu: I think this should have a `StartupInfo` prefix. As it's a field that goes into the StartupInfo struct
Josh: I agree
The 8742: They're all unstable. We could rename all the other ones.
Josh: +1 for removing the prefix from all of them. We've tended in Rust to shy away from APIs that make a convention of renaming everything to start with teh same prefix
Josh: I think we start an FCP on this, check boxes and post something to the other startup info functions issue to ask for removing the prefixes there.
Josh: I can start the FCP on this one, could someone else post on the other issues?
Amanieu: Sure.
### (nominated) rust.tf/153469 *docs: clarify path search behavior in std::process::Command::new*
Chris: How much you want to guarantee here?
https://github.com/rust-lang/rust/pull/153469#issuecomment-4241670820
> There are a wide variety of Unix (and unix-like) systems so my personal instinct would favour being cautious about what we guarantee. But that is a very tentative opinion. And I do think it's useful to document the current behaviour in any case.
Chris: On Windows I want us to chaneg things in the future. I don't know how the unixes would be with that guarantee.
Nia: The unix one at least feels like a reasonable thing to do. I don't see anything else that we could reasonbly do on unix. The windows one I'm not familiar with.
Chris: The Windows one has a whole history. It was broken for a while, then fixed.
The 8472: Since this has security implications, having some flexibility there (like Windows has shown) might be a good thing.
Nia: Fair.
Josh: At least it makes sense to allow some impylementation flexibility on Windows. And say it may be evolved further to address security issues.
The 8472: We have the platform-specific behaviors section. Maybe move it there.
Chris: SOunds good.
Josh: Yes.
Josh: But the thing for unix sounds like the windows thing: document the current behavior, document that we may evolve it in the future with care. But we don't have any specific plans for unix. I don't think we'll change the "search the child behavior".
Chris: So just a general disclaimer taht it might change.
Josh: "this behaviour can change based on OS changes or standard library bugfixes"
Chris: Makes sense
Nia: This makes sense.
Nia: Do we want to keep the ones for unix? Or do we guarantee to that one?
Josh: I think we add the generic disclaimer to the top of the platform-specific section.
Nia: That's fair.
Josh: For example: how does it handle the before_exact handler to cal setenv on PATH. That's something where we could decide to do differently and then have to document what we do in more detail.
Nia: I think that's fair. Is everyone okay with that?
The 8472: It's an important note, yes.
Nia: Yes. But do we want to commit to this?
Chris: I can respond.
### (nominated) rust.tf/154046 *Tracking Issue for \`alloc::io\` and \`core::io\`*
Nia: The idea is to add the modules but not stabilize anything in there. We'll probably have in there at some point. It's one less feature gate people will have to type. It's a guarantee we'll eventually put something in there.
Nia: It's a weak rationale but I do think something will happen there.
Josh: I think it's reasonably likely we'll put something in there. And it's reasonable to have a module with nothing in there so far. The only issue would be someone using `std` or `core` based on a feature flag and then trying to use `io`. It would produce a lot of error messages. But I think that's not a huge issue.
The 8472: It makes sense
Nia: I think we can thumbs-up this? Es4pecially since we thumbs-upped the alloc::io. Any objcetions?
Josh: Right now, we have gated the module by one feature that it's in the module. We'll have more things in there so I think it's fine to stabilise the module. The contents of it are behind various feature gates but there's no feature gate on the name of module feature gate.
Amanieu: This tracking issue has a `alloc::io` feature gate.
Josh: Sure. But it would be strange to have a feature gate for alloc::io and something inside `alloc::io`
Amanieu: Yes, you'd specify two features. I don't see a problem with that.
Josh: So you're suggesting we'd have an `alloc::io` and `core::io` feature gates, and when we stabilize something, we'd stabilize the module name then?
Amanieu: Yes. They don't have to be different features. They could both be under `core_io`
Josh: *shrug*
Amanieu: I'm happy to automatically stabilize them as soon as the first thing in them is stabilized.
Amanieu: I can reply.
### (nominated) rust.tf/154374 *Rename \`MetaSized\` trait to \`SizeOfVal\`*
The 8472: Did they post the summary?
Nia: It's on the zulip thread: https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/vibeck.20on.20Sized.20Hierarchy.20trait.20names/
Nia: lqd put together a hackmd doc here: https://hackmd.io/@lqd/BkyJXSInWx
Nia: The core naming thing for what we're looking at is: Sized (stable), MetaSized would be renamed to `SizeOfVal`, the next is `SizeOfValComputed` and the last one is currently `Pointee`: https://hackmd.io/@lqd/BkyJXSInWx#5-Custom-DSTs
The 8472: `SizeOfValComputed` doesn't sound great.
The 8472: What's wrong with `MetaSized`?
Nia: Nobody knows what it means unless you know Rust lingo and what that "meta" might refer to.
The 8472: We have the `Metadata` type in the pointer module
Josh: One of the possible changes is changing it from `MetaSized` to `MetadataSized` which is just annoyingly long.
The 8472: My goal is to design it in a way where the naming still makes sense once we have any value that's like a native C-string (that has to look at the memory, not our `CStr`)
Nia: That would be a level down.
The 8472: We need to distinguis those cases. The proposed `SizeOfVal` doesn't tell you how it's different. It doesn't look at the `Val` it looks at the `Metadata`.
Josh: That's true. The trait was named after the method `size_of_val` which is misnamed to begin with.
The 8472: Do we want to double-down on this questionable naming?
Josh: We need 2 operations: (1) look at this reference, metadata associated with the thick poniter and figure out how big it is, (2) look at the reference, look at the value itself and compute the size of that. And we can't use the name `size_of`. What would you call those given the constraints?
Josh: Note this is very bikesheddable and whatever we come up with here we should redirect to the thread.
Nia: This is also something the lang team is discussing internally.
Josh: They need to know what the names are so they can finalize the RFC. But it's reasonable for the lang team to delegate the exact naming to libs. That's with my lang hat speaking but I'm not speaking for the whole team.
The 8472: `MetadataSized` (or metasized) kind of makes sense. We have the unstable `metadata` method. That's the language we're moving towards. If we're moving away from that concept, we need to change those.
Nia: We're not moving away from that, just we need to describe how to describe it. For a slice, it's a metadata, for vtable it's different
The 8472: For a vtable it's a constant. IS there any data where it won't have a size?
Nia: No.
The 8472: We could say `MetaSized`, `DynSized` etc. It always relies on the dyn metadata.
Nia: I don't think we're ruling out other non-Sized things we could add later.
Nia: I'm still in favour of calling it `MetadataSized` or `DynSized` and have the other thing `ValueSized`. We could also call it "in-ptr sized" and "mem sized"
8472: If it were only references we could call it ref sized, but we also have wide raw pointers.
NIa: I liko 'MetadataSized' and 'ValueSized'
Josh: Of all that I've seen I like those the most. What would be the names of the methods?/
The 8472: Today we have `size_of` but if the hierarchy gets more complicated, then it makes sense to have differen names. We could have `slice_metadata`, `dyn_metadata`.
Nia: `size_of_val` is stable, right?
Josh: The global function is stable but badly named. We don't have to be consistent with that for the trait methods.
Josh: `size_from_metadata`, `size_from_value`?
Nia: The names that come to mind are `size_from_ref` from ref / by ref?
The 8472: The hackmd has additional cases. It has scalable vectors which are runtime-based. They have a size but it's not the size a common Rust size use. It would need a new name. And the last case is "things you can't point to". They call it "value" (it's not a pointee) so "size of value" would be more confusing then.
The 8472: That's why I asked for future possibilities. There could be conflicts with future names. Do we want to reserve space for those future possibilities? That makes the naming decisions even more difficult.
Nia: I'd say the scalable vector stuff will likely not interact with metasized or sizeofval ideas.
The 8472: I think it might. `size_of` is constant, right? So we need a new API that's not constant.
Amanieu: It can be conditionally const based on `T` being of the Sized conts trait. It's not stable but we have some support for it. I'm sceptical on this working out for scalable vectors. I'd expect us to fall back to treating them as extern types.
The 8472: So you can never `size_of` them?
Amanieu: Yes
The 8472: And there would be special methods to memcpy them?
Amanieu: You can pass them to values, but it'd be handled directly by the compiler in a special way. The size can be taken with a special instruction and the codegen method can handle it.
The 8472: The user code needs it.
Amanieu: They don't. There's an intrinsic you could use to load/store and tell you how big the platform is.
The 8472: If that's the case, we don't need to name
Amanieu: I don't think it's the current plan but it may end up happening
The 8472: Do we want to reserve space for this then?
Amanieu: No, that's already been ruled out. It will be decided on whether it Sized will be const or treat it as an extern tyep. We won't add it to the sized hierarchy.
The 8427: That simplifies one case but it still leaves the custom DST case and the unpointable extern ref thing. And the alignment.
The 8472:
```
const Sized // today's Sized types
!const Sized // scalable vectors
???? = Meta{Data}Sized, DynSized, SizeOfVal
???? = custom DSTs, like native C-strings (currently not our CStr)
???? = Size != Stride types
Pointee // extern types
Value // externref/unpointable types
```
Nia: Do we want to require Size == Stride for custom DSTs?
The 8472: They can sit in tail positions of various structs. I don't know the opsem model of the implications. I don't know whether it belongs above or below
Amanieu: I don't think it's ever going to happen
The 8427: People still ask for it
Amanieu: I know, I asked for it 10 years ago.
The 8472: We should reserve names for them.
Nia: for `Size != Stripe` I've no idea
The 8472: They don't have tail padding.
Nia: `PositionallySized`? Depends on where they are?
The 8472: Why do we reserve the padding at the end? I think this is so you can take some references to them? I think they'd have to be `MoveOnly` fields.
Nia:
```
const Sized // today's Sized types
!const Sized // scalable vectors
M{eta}dataSized // dyn, slices
ValueSized // custom DSTs, like native C-strings (currently not our CStr)
PositionallySized // Size != Stride types
Pointee // extern types
Value // externref/unpointable types
```
Amanieu: `PositionallySized` doesn't tell me anything
Josh: Do we want to move on to other topics now?
Nia: I'm happy to summarise this conversation and post it in the thread.
### (nominated) rust.tf/154406 *\`assert\_eq\`/\`assert\_matches\` vs \`debug\_assert\_eq\`/\`debug\_assert\_matches\` have different temporary scoping behavior*
Nia: This feels more like libs thing than libs API
Amanieu: It's been reverted already. I'll add a reply. We'll block the stabilization and we'd like a PR that introduces the scope. And we'd like to do the same for `assert_eq!` which is the only stable one. And we'll run crater on that. The one for `assert_eq!` will require an FCP. And as this is stabilized API so it will require an ACP.
The 8472: Would it effect the drop order?
Amanieu: It will, but hopefully you're not going to have assertions inside assert_eq
The 8472: If you used a mutex, you could lock order which would only be detected at runtime?
Amanieu: Let's do a test run, then?
The 8472: Yes.
### (nominated) rust.tf/154451 *Require that a \`\<\_ as Try\>::Residual\` implement the \`Residual\` trait*
Josh: This is from Scott. Is there an implication of sealing the `Residual` trait? It's not currently sealed but it could be before it's stabilized.
The 8472: If we seal it, nobody can implemnet it. ISn't the point of the `Try` trait that people can implement it for their own types?
Josh: Yes, but I was thinking of incremental stablization.
Nia: We can always have that conversation around the time of stabilization.
The 8472: I guess changing the bounds in either direction will be a breaking change?
Josh: Yes, once we've shipped it.
Nia: It makes sense that the type called `Residual` would implement `Residual` and I'm tempted to defer to Scott.
Nia: Seems everyone who knows something about this is in agreement of the core change. We can say that we're no experts here but it seems like a reasonable design decision. And that this isn't a guarantee of the absolute final decision.
Josh: I'd agree with that
The 8472: I've no opinions
Amanieu: I'm happy to defer to the experts
Josh: I'm eager to start using `Try` on stable
### (nominated) rust.tf/154834 *Stabilize \`tcp\_deferaccept\`*
The 8472: It's a linux specific API so there shouldn't be questions about portability.
Nia: Mark specifically mentioned: https://github.com/rust-lang/rust/pull/154834#issuecomment-4229695693
The 8472: Adding an underscore seems fine. And we don't have a nonzero `Duration`.
Josh: Mark's proposing to add a document for what happens with fractions.
The 8472: Do we have other native methods of that kind that take a `Duration`?
Amanieu: We explicitly say the `Duration` here is a maximum so it's allowed to be less in practice
Nia: Apparently it's not a maximum: https://github.com/rust-lang/rust/pull/154834#issuecomment-4188164991
> Another problem: the number of seconds passed also isn't a *maximum* either, it's a hint.
>
> For example, if you pass 8 seconds to this API, that will get calculated as 4 retransmits, which will wait up to 15 seconds worth of retransmits. (as of linux kernel tag v6.18 (2025-11-30) which is what I have easily available at the moment)
>
> This means that the duration can be significantly higher than the passed duration (up to 120 seconds longer in the most extreme cases I believe) or significantly lower (the duration is capped at 255 retransmits, which is about 29880 seconds or so if i'm doing the math correctly)
Nia: IT's a maximum based on how many retransmits it calculates
The 8472: I don't think `Duration` is the right choice
Nia: THat's my thinking
Amanieu: but it's still a time duration
Josh: The advantage of `Duration` is ??
The 8472: First it rounds down and then it rounds up during retransmit so it's very wobbly
Nia: The PR docs that it's suggestion mention rounding down to the nearest second as a `c_int`
Josh: I see what you mean. It gets rounded to the nearest second and then rounds to the retransmit. And we can't round it to retransmit, because that's in the kernel.
The 8472: If the underlying OS behavior is so wobbly we can't get much precision
Josh: We might want to be explicit about it taking seconds and rounding it up to some internal granularity. That seems like a docs fix but otherwise it seems fine.
The 8472: The man page doesn't even document this
Josh: It doesn't but it should.
The 8472: So we can't even say "check the documentation"
Josh: The upstream manpage is deficiant and should be impreoved to document to "round the number retransmits" behaviour. We should use `Duration`. And fix our documentation to say we pass to the current OS to seconds and then rounded internally.
The 8472: This is an optimisation so we don't have to be overly precise. We can just handwave and say this is approximate and not spend too much effort on it.
Josh: Sure
Nia: I like that. I think that's our response?
Josh: Yes to all and +1 to the rename with the underscore
Nia: +1
The 8472: Yeah
The 8472: I'll reply
Josh: Thank you.
The 8472: Josh, will you ping upstream on the man page?
Josh: I'll see what I can do.
### (nominated) rust.tf/154990 *Support creating default Vec within a custom allocator*
The 8472: There were concerns about inference failures?
Amanieu: It doesn't even pass CI because of inference failures.
The 8472: Close and say it's blocked until we have a way to guide inference?
Amanieu: I'm wondering if we could also do this over an edition? All the traits causing the inference we could do over an edition and ipmlement them there.
The 8472: Do we have a mechanism for that?
Amanieu: Sort of
Josh: This sounds like the default generic parameters bit. "I can geverate any Vec you'd like and if you have a specific Vec type with a specific allocator I could do that one. But if I haven't specified an allocator, I want you to do that one". That's been proposed for a while. We should check with T-Types
Amanieu: I talked to lcnr. The main issue is that it makes trait solving or type inference unbounded in complexity because it has to backtrack a lot.
The 8472: Is that in the library evolution thread?
Josh: I wouldn't expect it has to pick repeatedly. I thought it'd continue until youve discovered ambiguites, ??
Amanieu; Because of associated types, you can encode arbitrary function that's in the type system and you have to backtrack through that.
Josh: Oh boy.
Josh: So I think the response is: Blocked until ??
Amanieu: Unless we do it over an edition
Nia: Do we want this? Because this would break so much code
Josh: We want this if and only if it doesn't break all the things.
The 8472: If it's edition-dependent stuff then the edition migration would take care of that?
Amanieu: I'm not sure there's a way to do an automated edition migration. That's probably going to be discussed at the all hands.
Nia: Either way, it sounds like this is blocked for now.
Amanieu: Yes. I can add it onto the agenda for the edition stuff.
Nia: I'll reply.
### (nominated) rust.tf/155114 *Add \`Step::forward/backward\_overflowing\` to enable RangeInclusive loop optimizations*
Amanieu: We approved an ACP for this. This was nominated after the ACP.
Amanieu: There's one insta-stable change. PartialEq now returns false if either of the (old) `RangeInclusive`s is exhausted.
Josh: If we can make both `RangeInclusive`s better, than great if it's needed for optimizing both. But if it's just for the old one, I'm less in favor.
Amanieu: I believe this affects `RangeIterator`s. The old ranges and the iterators for the old ranges. The breaking change is only for the old `RangeInclusive` and there's no issue for the new ranges.
Nia: Either way it's something that would require a crater run. I think the behaviour is reasonable
Amanieu: The main issue is that `PartialEq` for `RangeInclusive` is now potentially incorrect. If either range is exhausted, this returns `false` saying they're not equal. Technically if it's exhausted.
The 8472: The fields aren't public, right? I guess it's no differnt from the floats? where NaN != NaN?
Amanieu: Yes. Though we implement `Eq` for it as well. I don't think this is valid.
The 8472: Since it implements `Eq` it wouldn't be valid, exactly.
Amanieu: AN alternative definition would be to say all exhausted ranges are equal. But that's still a breaking change.
The 8472: This goas back to the question of does this also change iterators on the new ranges?
Amanieu: Yes but thoes don't implement PartialEq so that's fine
The 8472: Can we make the changes onlly on those?
Amanieu: Yes
The 8472: That's what he suggests in the notes on the lasst paragraph
Amanieu: Yes and that waht this PR does
The 8472: Let's not do it on the old ranges then
Amanieu: It would be a nice speedup
The 8472: We already have the nice speedups on ??.
Nia: How difficult would it be to rever this to the old implementation without th ebreaking change?
Amanieu: Easy, we just remove half of this PR. This PR speeds up rangeinclusive iteration. The old PartialEq had a exhausted flag that started ??
Amanieu: 2 possibilities. Either just do it for the new ranges. We all agree on doing that on the new ranges?
Nia: Yes
The 8472: As long as we demonstrate the speed up. But as a first step don't affect the public API and do this only on the new ranges.
Amanieu: Yes. Now about the old ranges, there may be ways to change invalidating the old behavior. There may be a awy to change that by makeing it so that if it's exhausted, ignore start for the purposes of comparison.
The 8472: The type system allows that for any eq implementation
Amanieu: I think that might be fine? We could try the crater run on that. That would give us a speed up for the old ranges too.
Nia: I agree I'd like to see the benchmarks on this.
The 8472: Do currently the exhausted and empty ranges compare equal?
Amanieu: No they do not.
Amanieu: For the benchmark, there's this link from the ACP: https://rust.godbolt.org/z/xvhbf6zf5
Nia: Makes sense
Nia: What are you proposing then?
Amanieu: We accept this but change how PArtialEq works in a different way: if range is exhausted, we ignore the start field for the purposes of comparison. So if you're comparing two exhausted ranges, you're just checking that they have the same end point
Amanieu: That's technically a breaking change but arguably make it more correct?
Amanieu: Yes. RangeInclusive is fused. So I think that would work. Are people okay with this proposal?
Nia: Yes?
The 8472: I don't work much with inclusive ranges so I don't have much intuition there. If we ignore the legacy behavior I'd be okay with just that.
Amanieu: That's happening anyway.
The 8472: I'm not sure it's worth doing that then.
Nia: This would be a performance boost on the old ones too.
The 8472: No strong opinion.
Nia: Thumbs up on Amanieu's proposal by reason of "meh"?
Amanieu: I can reply.
### (waiting on team) rust.tf/153261 *Partially stabilize \`ptr\_alignment\_type\` as \`alignment\_type\`*
### (waiting on team) rust.tf/155113 *Ensure Send/Sync impl for std::process::CommandArgs*
Nia: Reasoning based on the safety doc there's nothing that could possibly be non-Send or non-Sync. It's just a slice iterator. I think it's reasonable.
The 8472: We need to FCP it.
Nia: Yes.
The 8472: It's only changing out implementations, not explicit type.
Nia: It's adding a trait. That would be externally visible
The 8472: It's an internal trait that gets propagate via the autotraits. Do we consider autotraits stable?
Nia: I think so. But I don't think we have a general policy on autotraits. I'd consider it as any other trait implementation.
Nia: Either way, it doesn't hurt to FCP it. The next item on the list is identical.
Amanieu: We should have the same resolution for both.
The 8472: Both of those are downstream of something we made portable that wasn't portable. Defacto we're not currently consistent with autotraits and didn't pay much attention for thos.
Nia: Seems like it. For this one I think it just makes sense to FCP it.
The 8472: Yes.
### (waiting on team) rust.tf/155153 *Ensure Send/Sync is not implemented for std::env::Vars{,Os}*
Nia: This one is trickier because it's removing a negative impl.
Amanieu: Let's do a check run?
Nia: I think these are all tier-3 targets?
The 8472: If you look at the rustdoc of the current Vars/Os, nothing changes on linux
Nia: I don't think this is a breaking change?
Nia: I think both of these are FCP approve
Amanieu: the Vars one are not going to show up in crater
Nia: But they're both tier-3 targets
Amanieu: I'm happy with this change.
### (new change proposal) rust.tf/libs776 *Add wide division method(s) to (unsigned) integer types*
Josh: My first reaction: this is probably going to be great other than trying to name them. It returns quotient remainder. So at the very least it should be `wide_div_mod`
Josh: Should this be "narrowing_div_mod" since we have "widening_mul"?
Nia: But the API doesn't look like it's narrowing
Amanieu: Is this even necessary?
Josh: The claim is it could be more efficient. It matches what div does on x86_64. It's 128/64 to 64 and 64 remainder
Amanieu: If the compiler can see that the high bits of the divisor are zero and you ignore the bits of the ??
Josh: You're taking 128 over 64 and it can't necessarily know that it's not going overflow
Amanieu: It can if you've just cast it from a `u64`. You take the 128-bit division and you take the divisor. If that's just been cast from u64 it should be able to use the instruction directly
Josh: You're saying if you cast the dividend and the result to u64 it can do it?
Amanieu: Yes and I'm pretty sure it does that
Josh: My other question is what is the behavior if the quotient doesn't fit
Amanieu: I don't know
Josh: That's important
Nia: Right now that should be just an open question according to the solution sketch?
Amanieu: `div` (the cpu instruction) will just wrap most likely. Unless you're dividing by zero.
The 8472: Do arm and risc-v have simiilar stuff? OR is it 64-specific?
Amanieu: I was wrong, LLVM will not optimise it. The reason why the x86 instruction is not used for wide division is that it raises an exception if the result doesn't fit. Which is why LLVM is not using it.
Nia: But then it makes this ACP not quite work. At most this would have to not go through LLVM.
Josh: I'm trying to remember whether there's a standard mode that supresses the DE exception
Amanieu: It says SIGFPE and I don't think you can disable it
Nia: If we have a way to get LLVM to optimise this better by doing it directly then maybe? But as is I don't see a reason to approve this. Would there be an agreement on "show us an implementation that's actually using the div instruction, otherwise no"?
Josh: The fact the intrinsic has a branch that handles the case for "you're dividing something that has the high bits of zero" does lower trying to get the efficiency here. We should post what we discovered here.
Josh: That's not a "no". If someone comes here and shows us what it saves then sure. But since the last response was that they hadn't seen that optimization in compiler-rt, I think we should not do this yet.
Nia: Is everyone cool with that? If so I'm happy to type up the reply.
### (new change proposal) rust.tf/libs775 *\`unchecked\_wrapping\_rem\` and \`checked\_wrapping\_rem\` for \`iN\`*
Josh: If you do the one and only case that's capable for overflowing then you'll either UB for unchecked or None for checked. Presumably if we wanted to do this we'd also want the strict version if we don't already have it.
Nia: That makes sense.
Josh: The distinction is: they want to silently return 0 for the "mod -1" case but they want to be checked/unchecked for the "div by 0" case
the room: WHY?
Amanieu: Technically for "int mod -1", the correct remainder for the result is zero.
Josh: You're right
Amanieu: The division overflows but not the remainder. Can we just fix `rem`?
Josh: That's the right answer. ... Hang on, `wrapping_rem` already does that. The description is not quite right, but it does do the correct thing.
Amanieu: The mod implementation says that it panics if the division overflows.
Josh: Sure, but we should say that the division might overflow but the mod doesn't so that's fine.
Amanieu: Does C say it's undefined behavior?
Josh: *groan*
Amanieu: In C the modulo behavior is defined in terms of the division operator which is then undefined. We do the same in Rust.
Josh: Should we?
Amanieu: Yes.
Josh: As opposed to observing that semantically it is not an error?
Amanieu: If we allow this, on ?? you'd trigger an exception on the overflow
Josh: wrapping_rem says "in such a sense the function returns 0". So it must be handling it differently than calling "div". So we can clear up the documentation and leave the behavior.
Amanieu: What they want is want wrapping rem that ??
Josh: I see. So what we have is strict wrapping rem and they'd like the other two variants of wrapping rem that don't panic
Nia: That's reasonable I think. We have one of the three that we normaly have. And this is a legitimate thing you might want to use.
Josh: This is not the "last five minutes of the meeting" question. I'd like to improve the documentation, but I get where they're coming from. But that's adding a lot of adjectives to each function.
Nia: Agreed. But we can just defer this for next time.
Josh: +1
Nia: I'll do it.
### (new change proposal) rust.tf/libs774 *Combined \`div\_rem\` function (and variants) for ints and uints*
### (new change proposal) rust.tf/libs773 *\`ptr::sentinel\`: \`ptr::dangling\` that cannot alias valid pointers*
### (new change proposal) rust.tf/libs771 *introduce an accessor method for \`std::fs::ReadDir\` that lets us get the path associated with the \`ReadDir\` iterator*
### (new change proposal) rust.tf/libs770 *NonZeroLayout for Allocator*
### (new change proposal) rust.tf/libs769 *Allocator: split deallocation into its own trait*
### (new change proposal) rust.tf/libs743 *ACP: Opt\-in to calling GlobalAlloc in std's internals*
### (new change proposal) rust.tf/libs688 *Initial state once cell value*
### (new change proposal) rust.tf/libs659 *Generalize ExactSizeIterator to QuantifiedIterator*
### (stalled change proposal) rust.tf/libs462 *impl fmt::Write for BufWriter*
### (stalled change proposal) rust.tf/libs523 *Add a deterministic constructor for \`RandomState\`*
### (stalled change proposal) rust.tf/libs331 *Support permanently skipping tests on a specific system*
### (stalled change proposal) rust.tf/libs192 *Report allocation errors through the panic handler*
### (stalled change proposal) rust.tf/libs457 *APC: split\_pattern on slices*
### (stalled change proposal) rust.tf/libs544 *\`Arc\<impl !Sized\>\` constructors*
### (stalled change proposal) rust.tf/libs111 *Restructure ptr\_metadata to minimal support*
### (stalled change proposal) rust.tf/libs420 *Add basic tempfile API to stdlib*
### (stalled change proposal) rust.tf/libs246 *ACP: replace use of \`Pointee\` trait with a \`ptr::Metadata\` type*
### (stalled change proposal) rust.tf/libs501 *ACP: Add floating point representation conversions*
_Generated by [fully-automatic-rust-libs-team-triage-meeting-agenda-generator](https://github.com/rust-lang/libs-team/tree/main/tools/agenda-generator)_