---
# System prepended metadata

title: Libs-API Meeting 2026-04-07
tags: [Minutes, Libs Meetings]

---

# Libs-API Meeting 2026-04-07

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

**Meeting Link**: https://meet.jit.si/rust-libs-meeting-crxoz2at8hiccp7b3ixf89qgxfymlbwr
**Attendees**: Amanieu, Nia, The 8472, Josh, Nurzhan

## Agenda

- All Hands sessions repo
- Leadership Council brief update
- Triage
- Anything else?

## All Hands sessions repo

Nurzhan: If you want to host a session at the All Hands (and, e.g., need a room reserved or something shown on the schedule), please create an issue in the repo: https://github.com/rust-lang/all-hands-2026 (see [this Zulip topic](https://rust-lang.zulipchat.com/#narrow/channel/532959-all-hands-2026/topic/Sessions/near/583991248) for context)

Nia: I might want to do something about allocators. If anyone has ideas, we can discuss.

Josh: This includes the baseline session where the libs team sits down and discusses issues. We'd need to file that as well.

Amanieu: IIRC, we have 3 days of AH. We want to leave the third day's agenda open and decide what to put there during the first 2 days.

Josh: Agreed. We should balance it. We should have individual items filed for what we want to do so we can figure out scheduling, conflicts, etc. We should have a catch-all with at least 2 hours for general library stuff.

Nia: We could put that on day 3, as Amanieu suggested. For the other 2 days we could schedule ad hoc things instead of reserving big blocks.

Josh: Makes sense with caveat: we also want to schedule 1h or 2 at the beginning for prioritizing items.

Amanieu: I want a session on next edition and possibility of making breaking API changes.

Josh: I'd love a design session on finishing up additions to std. For example, std::random, and ByteStr in std. To see if we could come up with designs ready for FCP.

Nia: Should we put these as individual issues?

Josh: Yes, but we need to keep track of these.

Nia: We can file the suggestions after the meeting and amend stuff later.

Amanieu: Do we want a session on restructuring the libs team? I don't have a firm plan.

Josh: Might be a good thing to talk on the "how are things going" first couple of hours session.

Nia: Makes sense. We can put that at the start of AH.

Josh: One scheduling caveat: other teams might have the same idea. If several teams do that, there will be overlap between members.

Nia: The first day is probably going to be light on prescheduled stuff. The events could be offset over the day.

The 8472: Do we need to specify specific times?

Nia: We can but don't have to. If there's a strict time req, we can request that specifically. Otherwise, we can be vague-ish, say "the first half of the day".

The 8472: That should simplify constraints

Josh: The 4 hours on the last day could be two 2h sessions for easier constraint solving. Given how it went last year, where people planned on the fly and wanted to be everywhere, I appreciate having the repo.

Nia: So, 4H on D3, 2H on D1, 3-4 individual sessions (editions, additions, allocators).

Josh: We can file more things later. There might be something about evolution of the standard library API in traits, since we're getting more features for trait-based evolution (supertrait shadowing, etc.). If we end up with those mechanisms, we might want to traitify more of the standard library.

The 8472: I saw a thread about that in t-types. Methods on traits fall under types, e.g. Read and ReadBuf API, right now there's an unstable feature. Does it fall under that?

Josh: Not sure why we never stabilizaed that, but it does fall under that.

The 8472: It's a crude design, not ready for stable.

Amanieu: IIRC, we were waiting for final methods?

The 8472: Final m we need for sth else. For Read we needed "implement one or the other"

Josh: Final methods are actually available on unstable now, since about a month ago.

The 8472: We had something that was blocked on that. Maybe it can make progress.

Amanieu: Was it ReadArray?

The 8472: That one, maybe.

Josh: I'm all for that one being marked final.

Amanieu: Yes, it's blocked on that because it has a Sized bound. We don't want anyone to override this.

Nia: Do we want to discuss that at the AH?

Josh: That one we want to unblock, but yes, there's a lot to discuss there.

## Leadership Council update

Nia: Are we doing LC update meeting?

Josh: I wanted to mention the fact of LC meeting happening.

Josh: Appreciation to libs teams for trusting me with repr them on LC. The next meeting is this Friday. There aren't a lot of issues to discuss since this is the first one. AI policy is the primary issue ATM. I wanted to expl ask if people think we should discuss LC items in this meeting. It'd be probably redundant to discuss these in both meetings.

Nia: My pref is to discuss it tomorrow at the libs meeting, for timing.

Josh: No strong preference as well. The libs meeting is 30m?

Amanieu: Yes.

Josh: I wasn't aware if it'd been formally shortened. I can imagine crowding that meeting with the LC items. We can deal with that if it happens and schedule something else.

Nia: If there's a lot to discuss, we can discuss it at the libs-api meeting.

Josh: I'd be cautious because of the different team membership. I'm fine with leaving it for the libs meetings, just highlighting that there might be the timing issue.

Nia: Then my preference is libs-api.

Josh: Then we should bring it up in tomorrow's meeting for people to be able to weigh on it.

Nia: I'll put it on tomorrow's agenda.

The 8472: We should also see what's in those updates  how relevant they are to the team.

Josh: Absolutely.

Josh: If there are items that folks want brought up at the LC level, feel free to do so async with me or in the public libs channel. I want to make myself available for this.

Nia: Let's make a Zulip thread on this. I'll set it up.

Josh: Perfect.

## Triage

### FCPs

19 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/139690 *\`impl Default for RepeatN\`* - (3 checkboxes left)
  - merge rust.tf/153873 *deprecate \`std::char\` constants and functions* - (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\`* - (4 checkboxes left)
  - merge rust.tf/138215 *Tracking Issue for integer formatting into a fixed\-size buffer* - (4 checkboxes left)
  - merge rust.tf/153990 *Decide and document where stdarch intrinsics are allowed to diverge from asm behavior* - (4 checkboxes left)

[scottmcm (1)](https://rfcbot.rs/fcp/scottmcm), [BurntSushi (12)](https://rfcbot.rs/fcp/BurntSushi), [joshtriplett (11)](https://rfcbot.rs/fcp/joshtriplett), [Amanieu (2)](https://rfcbot.rs/fcp/Amanieu), [nikomatsakis (1)](https://rfcbot.rs/fcp/nikomatsakis), [dtolnay (4)](https://rfcbot.rs/fcp/dtolnay), [the8472 (13)](https://rfcbot.rs/fcp/the8472)

### (nominated) rust.tf/126769 *Tracking Issue for \`substr\_range\` and related methods*

Nia: FCP finished. Renominated (do we want to return the old or new range). Should be merged?

Amanieu: New range, please.

Nia: Assumed so.

Amanieu: Given a substr that's inbounds of a larger string, give me the range of that substr within the larger string.

Nia: Sounds correct.

The 8472: New sounds fine. Has anyone brought up reasons not to return the new range?

Amanieu: No.

The 8472: Let's do it then.

Amanieu: Do we need to restart FCP?

Josh: Did we already add the Into impls between old/new ranges?

Nia: I think yes?

Amanieu: We should have.

(Yes, we did.)

Josh: These read confusingly (`impl From<Range> for Range`), maybe they should include the module.

Nia: This doesn't really require a new FCP since it's small.

Amanieu: Maybe someone has an objection to that, so we should be conservative.

Josh: We're not in a rush.

Amanieu: Is anyone familiar with rfcbot to tell if we can restart the FCP?

Josh: (Explains.)

Amanieu: I'll take care of this.

Nia: We're in agreement to start FCP?

(Yes.)

Josh: I'll also report the impl presentation issue to rustdoc.

### (nominated) rust.tf/149926 `P-lang-drag-1` *Do not deduplicate captured args while expanding \`format\_args!\`*

### (nominated) rust.tf/152480 *\`format\_args!\`: only de\-duplicate captured identifiers that refer to places*

### (nominated) rust.tf/154374 *Rename \`MetaSized\` trait to \`SizeOfVal\`*

Nia: Discussed on Zulip. We got pulled into this for naming. I don't like `SizeOfVal` that much.

The 8472: Semantics?

Nia: Size of the type is stored in ptr metadata.

Amanieu: It's a superset of Sized.

Nia: This is only for those where size is in the ptr metadata.

The 8472: CStr, e.g., if we do strlen, if we rename it to SizeOfVal, it sounds like it would cover that too.

Nia: That was my thinking as well. I don't think we want to support that in the future...

Josh: `SizeOfVal` and `const SizeOfVal` are both in plans. If not const, you have to figure out the size based on runtime metadata. I *think* the use case for const is for scalable ARM vector register sizes, where it's known at runtime but is a global constant and is known *to be fixed*. Amanieu, can you explain better?

Amanieu: Size is known at runtime, not compile time, but is a global constant for the runtime of the program.

The 8472: Doesn't change across cores?

Amanieu: No.

The 8472: How would we name the thing for CStr?

Amanieu: MetaSized?

The 8472: You mean ValueSized? You need to look at the value, not the metadata. It has opsem implications.

Nia: Right now we have that as PointeeSized, but that's a bad name

The 8472: So it exists?

Nia: Yes, but not implemented ?? I don't think it can do anything besides being the most relaxed.

Josh: Not aware of PointeeSized being implemented.

Nia: It's a marker trait.

Josh: OK.

Amanieu: I think they have different purposes.

Nia: I think so.

The 9472: It's basically called `SizeOfVal` because we're going to add it to `size_of_val` and then the method says "you can use this on everything, some types you need to call smth else to get it"

Josh: size_of_val method now is smth we don't put a bound on, and if it turned out that smth was not sizeable from a value, we'd have to fail/panic. WE could add SizeOfVal as the bound, as it would no longer have the ability to fail.

The 8472: I was asking if that was the plan.

Josh: That was my understanding modulo transition.

The 8472: The method is consistent with trait requirement, and some types are excluded from that.

Nia: `SizeOfVal` tells you mothing about what it is out of context. It doesn't make me think that the size is attached to the pointer (?). If MetaSized is too obscure, we could name it MetadataSized

Nurzhan: DynSized, Unsized?

Josh: 

Nia: `DynSized` is fine if you know what it refers to, but could be mistaken for "dynamic size".

The 8472: dyn is ...

Nia: The first reading is still "dynamically sized", not `dyn`-sized.

The 8472: `dyn` is Rust-specific, so it could be fine.

Nia: I'd be fine with `DynSized`. We name traits either verbs or ... but SizeOfVal is weird.

The 8472: Concern: what if we have smth like CStr, smth that needs to look at memory to figure out the size. What's the trait for that? Once we figure it out, things will make more sense.

Nia: Most people ?? at the idea of supporting CStr, arguing that it makes opsem hard.

The 8472: IT doesn't have to be CStr. Could be a custom FFI type where it's dynamically allocated and you need to call some method to get its length (dynamic arrays, etc)

Josh: There will need to be support for that, yes.

Nia: ... pass some function pointer that knows how to extract the size... That would not be `size_of_val` but something else, taking a pointer and some function.

Josh: SizeOfVal as a name is designed around the concept of figuring out the size from the value, but ... metadata; there's no reason why it can't work with ... that's ambiguous and would be confusing is SizeOfVal and ValueSized were both a thing. We should think about the naming together (size by metadata vs size by value). MetadataSized, DataSized?

The 8472: SizeOfValRaw?

Josh: We do have size_of_val_raw that takes...

Nia: The only difference is that it's unsafe, I think.

The 8472: It still only looks at the metadata, right?

Nia: Yes, in the current impl (as MetaSized).

The 8472: ...a separate API for things that are memory-sized... or same API with assoc type on the trait that tells us where to look at the size

Nia: We can figure out the details later, but I like the idea.

The 8472: Do we want to keep the API and make it more detailed, or a new API ... if we don't know the semantics, we will struggle with naming.

Josh: https://github.com/rust-lang/rust/issues/154960

Nia: I have an idea of how we can do this. Keep MetaSized, and for CStr we can have MemSized or InlineSized where instead of size_of_val we'd have size_from_mem or whatever, which takes a pointer and is generic over the type, and you have to manually impl some InlineSized trait with get_size method...

The 8472: Then how will you write generic code... Usually you can pass ??, but if you have two different methods with different behavior you'll need specialization or ...

Nia: You're right.

The 8472: If there's a constraint that forces us to do that, we may have no cohice, but I'd like to avoid it.

Nia: I'll try to sketch smth out for CStr and show them, and we could defer until next week.

The 8472: I don't think we should map the API out. We need to figure out how it works (?) to figure out naming.

Nia: Then we defer for next week.

### (nominated) rust.tf/154765 *Clarify ascii whitespace exclusion of vertical tab in the doc*

Nia: The situation is that is_ascii_whitespace doesn't treat the vertical tab character as whitespace, while is_whitespace does. This is correct because it might break stuff subtly if changed.

The 8472: One is Unicode, where does the other come from?

Nia: For Unicode, this is whitespace, but...

The 8472: Where are we getting the ASCII whitespace definition from?

Josh: I suspect Rust history. Rust lexer does include the vertical tab as whitespace...

The 8472: Feels odd that someone grabbed definition from some spec...

Josh: I'd be surprised if people referenced that when adding the method.

The 8472: It actually is in the method documentation.

Josh: I stand corrected.

The 8472: Introduced in 1.24. Someone must have gotten the idea from somewhere.

Josh: The first time I've heard of the WWG standard

The 8472: Maybe it was picked because it was consistent with other users in the wild.

Nia: Seems like a web standard of some kind.

The 8472: We're not going to change it anyway, the doc change is fine.

Josh: We could entertain the possibility of changing it and seeing how much it breaks.

Nia: ??

The 8472: Someone might be using it for network protocols. If we change it, someone is technically not compliant anymore.

Josh: You're not wrong.

Nia: Ugly, but we can merge the PR.

Josh: We could introduce a change over an edition (is_ascii_whitespace_fixed).

The 8472: It's not really broken if specific protocols require this definition. But we could pick a more precise name.

Josh: I wasn't trying to be normative about the name...

The 8472: Is the ASCII subset of the Unicode definition...

(Agreement to merge.)

Nia: I'll reply to them.

### (waiting on team) rust.tf/153261 *Partially stabilize \`ptr\_alignment\_type\` as \`alignment\_type\`*



### (new change proposal) rust.tf/libs772 *Maybe: expose \`transmute\_unchecked\`*

Nia: This is different to transmute, something about size check.

The 8472: We already have transmute_copy, which is more relaxed. The difference is that this is by value, not by ref.

Nia: Seems like it.

Josh: Interesting that something `_unchecked` is in fact checked.

Amanieu: `transmute_copy` is impl as cast-to-pointer, then read dst. If Dst is smaller, it will read the prefix or Src, otherwise it will read more data than Src. transmute_unchecked is basically transmute, but without the compiler checking sizes.

Josh: I'd not expect transmute_unchecked to check sizes

Amanieu: It requires sizes to be the same... allows using transmute to be used in generic context.

Josh: Wouldn't const_assert fail in that case?

The 8472: Depends on whether the generic is instantiated

Amanieu: ?? `transmute` checks that the sizes are the same pre-mono.

The 8472: ?? 

Amanieu: Don't think it's possible to do better pre-mono.

The 8472: Someone wanted to move it to post-mono? I thought we were changing transmute itself rather than a new approach.

Josh: 1) whether it'd be possible to change transmute; 2) if we need transmute with const_assert post-mono rather than pre-mono identical check, I don't think it should be called `_unchecked` because it is checked, just differently.

Nia: I'd argue that given there's some work on transmute, and that this is implementable as library code, we should say let's make transmute post-mono.

The 8472: The API/compiler ppl might have opinions...

Nia: This is something that can be done in lib code, and the motivation is mainly "this is annoying to write". Let's not add a method we'll likely deprecate in the future.

Josh: We should give feedback to check with t-compiler that changing `transmute` to this is impossible. And also that the method shouldn't be called `transmute_unchecked`. We shouldn't specify what it *should* be called.

Nia: Do we agree?

The 8472: Sounds OK.

Amanieu: Josh, are you arguing that transmute should become what's proposed here?

The 8472: IIRC, the suggestion was to keep the existing check but make a lint if the compiler cannot determine this in generic code, and have a post-mono error as a safety net.

Amanieu: Sounds good with a lint (even deny-by-default), otherwise I wouldn't be comfortable with a post-mono error.

Nia: I'll reply. We propose that the author talks to t-compiler, but right now we don't want that function because it could get deprecated.

Amanieu: I'd say that as a team, we're proposing this alternative, and the author can ask t-compiler if it's OK.

Nia: OK.

### (new change proposal) rust.tf/libs771 *Introduce \`std::fs::owned\_read\_dir\` and an accessor method for \`std::fs::ReadDir\` that lets us get the path associated with the \`ReadDir\` iterator*

The 8472: Their motivating example is... not sure if that's a good idea because they'd have to keep a buffer of all the seen directories. Usually, `remove_dir_all` is implemented depth-first, but it's tricky for security. Not sure if the motivation is that right.

Nia: Don't see other motivations. Basically, we don't want to .. reference

The 8472: ...access to internal buffer that they want to mutate? OK, it takes a `PathBuf` and returns a `&Path`... I think those could be implemented... not sure if on all platforms..

Nia: Not sure.

Josh: I feel like these are 2 separate concerns (the in and out).

The 8472: Not sure if they're even proposing to get it out, just to have a reference.

Josh: I guess so. If there were such an accessor, I'd like an Into impl.

The 8472: The `??` iterator is probably more expensive than `PathBuf`, unless you're really deep into directory... that exceeds the 4k limit. If this is only motivated by a single use case, and that's an open PR to have a breadth-first remove_dir_all, then I don't think the motivating PR is a good idea. By proxy, this ACP isn't well-motivated.

Josh: `read_dir` takes `AsRef<Path>`. I wonder if there'd be value in specialization. ??. I think that's sensible. We could do that with read_dir with enough care.

The 8472: The specialiation should work. ?? zero, we'd need to reallocate anyway to add a null-terminator.

Josh: Sure, we might already have capacity in the Vec, it'd be more expensive than copying. We could trivially add ??. We could do spec on `std::fs::read_dir`.

(...)

Josh: Proposed response: We should reject `owned_read_dir` and instead try to make `read_dir` do that. We should consider having reverse method for getting out of `ReadDir`, but we'd need to evaluate platforms and have it unstable for a while. It also shouldn't be called `root`. 8472, you're the person on the team with most understanding of specialization. Can you write it up?

The 8472: Sure, can do.

### (new change proposal) rust.tf/libs770 *NonZeroLayout for Allocator*

Nia: This is changing the arguments Allocator takes to have non-zero layout type. The argument is that some Allocators cannot handle ZST allocations, the ?? should be on the caller side.

The 8472: It's not rlly a layout/type because zero-length Vec also has ZS layout, so it's a runtime thing that we cannot elide in all cases.

Nia: Agreed. I have a slight pref to keeping the layout as is. AFAIK, most allocators are fine with this. libc malloc is allowed to behave weirdly, and jemalloc(?) ??.

Josh: Is this primarily about optimization?

Nia: Yes.

Amanieu: The motivation is wrapping an allocator, and passing ?? is UB. I'd like to avoid having a zero check in my allocator.

The 8472: Converse cost: If you know your allocator ?? and returns a ?? pointer, you can ?? which unlocks more optimizations because ?? the pointer always flowing from allocation side, but we cannot acutally exploit this property because something with Box::new in const. It'd only work at runtime, or you'd need the property that allocator accepts freeing any ZST deallocation.

Nia: The sokution they bring up in the ACP is to havea different method where you can take ZST if you know allocator can handle ZSTs.

Josh: That'd address the concern of what if you could make the rust-side check go away because you know your allocator handles that well.

The 8472: The proposed API forces non-zero layout?

Nia: No, it's to have another method. For size 0 it returns a dangling pointer...

The 8472: The solution sketch says...

Josh: I think it's important to capture that we want the version listed in the alternatives rather than the one listed in the solution sketch. IF we include the alternative, modulo naming, it has the potential for great optimization. Are there reasons to not do this?

Amanieu: I don't like the API complexity that this adds. Consider bump allocator, which doesn't need to special-case zero.

Josh: Anything more complex doesn't care.

Amanieu: It's a branch that will be correctly predicted.

The 8472: Still, pressure on the predictor.

Nia: I'd add that in the case of passing a dyn allocator, that might not be able to do the elision at compile time. ?? cost of making v-table bigger.

Amanieu: If the layout is known at comptime to be zero, ... people should handle outside of the allocator regardless of whether it supports ZST allocations.

(...)

Nia: Do we have any agreement? For the solution sketch with the alternative... it's complicated API but seems like it makes some people slightly happier.

Amanieu: I still don't like it for the API complexity. I'd prefer havong zero just work for allocators. It just makes the mental model simpler.

Nia: Yeah, it's what I prefer.

Amanieu: I'm hesitant to add so much complexity at least without a bench showing it's worth it.

Nia: Makes sense. Should we ask them for some?

The 8472: It could be code size, not necessarily perf.

Josh: Same thinking. It might not show up in metrics. I'd be more concerned about large numbers of allocators where eliminating the zero checks would have a greater impact.

Amanieu: ??

Nia: The case that comes to mind is jemalloc's UB on zero.

Amanieu: Yeah, it's jemalloc's internal API that has UB if the size is zero.

The 8472: Right now, Global has a [branch](https://doc.rust-lang.org/nightly/src/alloc/alloc.rs.html#205) in ??. So right now this kind of branch exists for all allocators. On the other hand, this isn't generic code, but once per scheduler or whatever.

Nia: Looking on Zulip to see what people are saying. Not seeing concrete examples of ZST allocations being an issue.

Amanieu: Bump allocation specifically doesn't need to handle zero.

Nia: https://rust-lang.zulipchat.com/#narrow/channel/197181-t-libs.2Fwg-allocators/topic/Pushing.20forward/with/579967709

(...)

Amanieu: If you need ZST allocations to not use memory, you should check with the ...

Nia: If you need something optimized to that level, you probably should write something custom.

Nia: Let's keep layout as is and not complicate further. We can also ask for benchmarks (binary size, perf or both).

The 8472: That'd be a start at least. If someone can show us a huge impact, that might shift opinions a bit.

Nia: Do we agree on asking for benchmarks?

Josh: Yes, we want to see something that makes a meaningful difference.

Nia: OK.

Josh: I think it's worth noting that we're generally pickier about what we give to our allocators than, say, C is. The fact that we do size deallocations and don't require ??, is precedent for ??.

Nia: That makes sense.

Amanieu: I'll also write a rant about why I don't like this.

### (new change proposal) rust.tf/libs769 *Allocator: split deallocation into its own trait*

Nia: I have opinions on this. We can do this without changing allocator with supertrait shadowing.

Amanieu: I think it's... (Josh: [supertrait auto-impl](https://github.com/rust-lang/rfcs/pull/3851)).

Nia: The proposal was to move the method to a different trait and require Allocator to be Deallocator. We can achieve this without having people implementing two impls.

The 8472: Allocator is very low-level, and you don't write those every day. The friction isn't that bad.

Nia: That's just one of the several points. We can achieve the same thing without requiring that. I'm also not convinced that you need separate allocators? My idea was to leave Allocator as is, and with supertrait bound we can add Deallocator later. It doesn't need to be blocking for stabilizing Allocator. I put a playground there with the idea.

Josh: The original proposal was to separate into two traits... and yours is to split them such that Allocator still has both methods?

Nia: Yes. Code that already impls Allocator wouldn't break if Deallocator is added because of the blanket impl. With supertrait shadowing, this wouldn't break users.

Josh: ... you'd have to delete the impl of Deallocator and...

Nia: Yes, you can't have both.

Josh: The original would require having two separate traits or impl via supertrait.

Nia: Yes, but it would still be ok to change the impl.

Josh: We don't need the new lang feature unless we get annoyed with impl two separate traits, right?

Nia: Yes. ... means that stabilizing Allocator would be blocked on stabilizing Deallocator as well.

The 8472: Splitting traits into smaller pieces is something we usually do when ... from that angle it seems like a good idea if it enables things you can't drop but can allocate?

Nia: Sometimes deallocation is a no-op, so Deallocator can be a ZST, letting you avoid holding a pointer to it. (m-mueller678 via GitHub comment: "Many allocators can derive all information necessary for deallocation from the deallocated pointer and layout.")

(Josh drops.)

(...)

Nia: I'll advocate for doing it in the way that doesn't block Allocator.

The 8472: Having two traits for two behaviors is fairly common. Seems simple.

Nia: I guess.

The 8472: If there are enough use cases, makes sense to have this.

Nia: I'm not convinced that there are enough to warrant this. Feels like we're adding a trait for 3 people who'll use this.

The 8472: Right now, very few use this because it's unstable. There will be more when this is stabilized.

(Discussion about some bump allocator crate being a common dependency, which could benefit from this...)

The 8472: So there's a bunch of API that could use ?? (Deallocator?) without Allocator available. Uncloneable Vec?

Nia: I don't feel that strongly. It just feels like a papercut for something that's used rarely.

(...)

Amanieu: There's a question of how do you create a type with a Deallocator only? The only way I can think of is `??_raw`.

The 8472: We should ask for additional use cases and how this will be used in practice.

Amanieu: I'd like to ask ... defer to later

Nia: I agree. Deferring feels right because there's a big design space. You can impl Allocator on a type now, and even if Deallocator is added with recursive impl magic, it'll still work without being a breaking change.

The 8472: That's the easy part. Relaxing an associated type could be a breaking change because then it allows more. If something has Allocator as assoc type, and then we change stuff...

Nia: Right now, Allocator relies on nothing...

The 8472: If it has a bound on Allocator, and then we notice that... but we don't have that. Should be fine.

Nia: Do we ask for use cases, approve?

Amanieu: Ask for good reasons why we can't defer this.

The 8472: We don't have to treat this as something to be stabilized with Allocator. We can accept this as unstable and stabilize later.

Nia: If we want to stabilize this later, then we'll have to use the shadowing stuff.

The 8472: Doesn't supertrait auto-impl...

Amanieu: That's not stable. supertrait auto-impl is not, but we don't need it here.

The 8472: If we keep Deallocator unstable and want to stabilize it later...

Amanieu: If we have a blanket impl for Deallocator for everything that impls Allocator, that should be enough...

The 8472: People would have to implement Deallocator twice?

Amanieu: No, because there's a blanket impl.

The 8472: OK.

Nia: I asked the trait-solver people, and they said it's fine.

The 8472: We can ask for 1) more motivation/use cases, 2) ask if there's any reason to not do this later, 3) think a bit further beyond Deallocator about how it would affect collections.

Nia: Agreed.

Amanieu: Yes.

Nia: I'm willing to reply unless someone volunteers. I'll do it.

### (new change proposal) rust.tf/libs768 *\`core::arch::return\_address\`*

Nia: They want track_caller but it gives you the pointer/return address for debugging.

Amanieu: It occurs to me that you can do this with track_caller.

Nia: The example given is across FFI boundaries where that doesn't work. This is not supposed to be something you rely on, only for debug logs. They want us to lower into some builtin return address gcc. Effectively this would be a debug thing.

Amanieu: I'm ok with it. Some say it should be a macro the same way line and column are.

The 8472: Is it a runtime value?

Amanieu: You want the return address of your function.

The 8472: Yeah, but that's still not compile time.

Amanieu: TRue, but it happens in the context of the current function.

The 8472: I see, it's more like an intrinsic.

Nia: I think this is fine. A bit of bikeshed is do we want ?? pointer or usize?

The 8472: Haven't we had code pointer or something?

Amanieu: That didn't get implemented.

The 8472: So we still don't have a precedent for how to point... but if it's a ZST it's fine?

Amanieu: As long as code address space size has the same size as data address size. Which is ...

Nia: But we might want to eventually.

Amanieu: No! The data pointer size should be the same as code pointer size. The archs where this isn't the case we don't support.

(...)

Nia: Want to return usize because doesn't have provenance.

Amanieu: Doesn't it? It doesn't.

(...)

The 8472: We can ask for reasons to not make it a usize.

Nia: Then that's fine. Should we say yes?

Amanieu: Yep. Also inclined to add frame address and stack address. The idea being, stack address is the value of the stack pointer right now, frame is the value on function entry.

The 8472: Usually cheap to obtain.

Nia: Frame pointer is trivial to get.

Nia: Sure. I'm cool with this. I'll type up a reply and mention the possibility of ACP for the other two.

Amanieu: And they should probably return usize.

Nia: They didn't want to because the intrinsic doesn't do that.

Amanieu: That's not a good reason.

Nia: You can either have it return a usize and ... without provenance, or ... pointer, and we treat the pointer as if ... without provenance. We didn't want to give people ideas that this is a normal pointer.

The 8472: ZST pointer is better. ?? don't have provenance.

Nia: There are some things about ZSTs that pointers now require.

Amanieu: ...

Amanieu: Also, a return address of null is valid. It doesn't need to point to executable code. It could point to garbage, we make no guarantees.

Nia: Fine, pointer to zst.

Amanieu: I prefer pointer to u8.

Nia: I'll reply. Also, we wanted a macro?

Amanieu: Always inline fn?

The 8472: People might want not to expose intrinsics... transmute used to...

Nia: Fair. Macro or fn? I think macro.

The 8472: Macro.

Amanieu: No preference. Author prefers macro. Let's do macro.

### (new change proposal) rust.tf/libs767 *\`Step::forward/backward\_overflowing\`*

Nia: This is about optimization.

Amanieu: The Step trait is unstalbe, so we can make changes.

Nia: It optimizes poorly, and if ..., the LLVM optimizes it better. Not sure if this is good reasoning.

Nia: Not sure if big deal. They have godbolt example.

The 8472: Shows assembly and not source for some reason.

Nia: First one is this:

```rust
#![feature(step_trait)]

use std::iter::Step;
use std::ops::RangeInclusive;
use std::mem;

#[unsafe(no_mangle)]
pub fn count_ex(s: u8, e: u8) -> usize {
    let y = s..e;

    let mut out = 0;
    for _x in y {
        out += 1;
    }
    out
}

#[unsafe(no_mangle)]
pub fn count_in(s: u8, e: u8) -> usize {
    let y = s..=e;

    let mut out = 0;
    for _x in y {
        out += 1;
    }
    out
}

#[unsafe(no_mangle)]
pub fn noop_loop_ex() {
    for _ in 0_u8..100 {
        ()
    }
}

#[unsafe(no_mangle)]
pub fn noop_loop_in() {
    for _ in 0_u8..=100 {
        ()
    }
}


// Same implementation as core spec with TrustedStep
struct MyRangeInclusive1 {
    start: u8,
    last: u8,
    exhausted: bool,
}

impl MyRangeInclusive1 {
    fn from(other: RangeInclusive<u8>) -> Self {
        Self {
            start: *other.start(),
            last: *other.end(),
            exhausted: false,
        }
    }

    fn is_empty(&self) -> bool {
        self.exhausted || !(self.start <= self.last)
    }
}

impl Iterator for MyRangeInclusive1 {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        if self.is_empty() {
            return None;
        }

        let is_iterating = self.start < self.last;
        Some(if is_iterating {
            // let n = unsafe { Step::forward_unchecked(self.start, 1) };
            let n = self.start + 1;
            mem::replace(&mut self.start, n)
        } else {
            self.exhausted = true;
            self.start
        })
    }
}

#[unsafe(no_mangle)]
pub fn noop_loop_in_my1() {
    for _ in MyRangeInclusive1::from(0..=100) {
        ()
    }
}

```

Nia: Second is this:

```rust
#![feature(step_trait)]

use std::iter::Step;
use std::ops::RangeInclusive;
use std::mem;

#[unsafe(no_mangle)]
pub fn count_ex(s: u8, e: u8) -> usize {
    let y = s..e;

    let mut out = 0;
    for _x in y {
        out += 1;
    }
    out
}

#[derive(Debug)]
struct MyRangeInclusive2 {
    start: u8,
    overflow: bool,
    last: u8,
}

impl MyRangeInclusive2 {
    fn from(other: RangeInclusive<u8>) -> Self {
        Self {
            start: *other.start(),
            overflow: false,
            last: *other.end(),
        }
    }

    fn is_empty(&self) -> bool {
        self.overflow || self.start > self.last // !(self.start <= self.last)
    }
}

impl Iterator for MyRangeInclusive2 {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        if self.is_empty() {
            return None;
        }

        let (n, b) = self.start.overflowing_add(1);
        // let (n, b) = if let Some(n) = Step::forward_checked(self.start, 1) {
        //     (n, false)
        // } else {
        //     (0, true)
        // };

        self.overflow = b;
        Some(mem::replace(&mut self.start, n))
    }
}

#[unsafe(no_mangle)]
pub fn noop_loop_in() {
    for _ in MyRangeInclusive2::from(0_u8..=100) {
        ()
    }
}

#[unsafe(no_mangle)]
pub fn count_in(s: u8, e: u8) -> usize {
    let y = MyRangeInclusive2::from(s..=e);

    let mut out = 0;
    for _x in y {
        out += 1;
    }
    out
}

fn main() {
    let mut a = 0_u8..=100;
    let mut b = MyRangeInclusive2::from(0_u8..=100);

    for _ in 0..105 {
        assert_eq!(a.next(), b.next(), "{b:?}");
    }


    let mut a = 0_u8..=255;
    let mut b = MyRangeInclusive2::from(0_u8..=255);

    for _ in 0..260 {
        assert_eq!(a.next(), b.next(), "{b:?}");
    }
}

```

The 8472: Specialization already uses `unchecked`, so why `overflowing`?

Nia: This smells like LLVM messed up, not on us to fix this.

The 8472: Unclear whether perf issues are due to forward_checked or forward_unchecked. If overflowing optimizes better, forward_?checked would be surprising. The commented out one should already...

Amanieu: My impression is that I don't mind changing Step. It's unstable and not in any shape to be stabiliing soon. What impact does this have on RangeInclusive? Is the behavior the same as before?

The 8472: It's basically like the current implementation, an if check, then... custom branching that advances the iterator or sets a flag, a manual overflow check. The proposal is replacing it with something that passes thru to the overflowing ??, so it directly fetches the overflow flag from registers, which optimizes things.

Amanieu: In prev impl, the overflow flag is sticky, so exhausted stays so. In the new, overflow flag resets to zero?

The 8472: ??

Amanieu: But self is not empty is range is 0..=255. This only moves the start, and after overflow, if ?? overflows, N==, b==true.

The 8472: is_empty checks the overflow too.

Amanieu: Missed that. Behavior is the same. Approved.

Nia: If same, then fine.

Amanieu: Ship it.

The 8472: Should we replace forward_checked then?

Nia: I'd leave it for now. Not very familiar with the APIs.

The 8472: ?? avoid the Option wrapping and unwrapping. It's a matter of low-level API vs cleaner semantics.

Nia: Who'd like to reply?

Amanieu: I can reply. We just approve?

Nia: Yeah.

### (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/libs544 *\`Arc\<impl !Sized\>\` constructors*

### (stalled change proposal) rust.tf/libs298 *Constructive/Destructive Interference Size Padding*

### (stalled change proposal) rust.tf/libs334 *Customizing \`#\[derive(Debug)\]\`*

### (stalled change proposal) rust.tf/libs207 *\`parse\_line\` method for \`Stdin\`*

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

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

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

### (stalled change proposal) rust.tf/libs501 *ACP: Add floating point representation conversions*

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

### (stalled change proposal) rust.tf/libs314 *Add security\_attributes() to windows::OpenOptionsExt*

Amanieu: Thought we resolved this.

The 8472: Don't remember outcome.

Amanieu: Author hasn't replied.

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