Try   HackMD

Libs-API Meeting 2025-06-03

tags: Libs Meetings Minutes

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

Agenda

  • Introduction of Tomas
  • Triage
  • Anything else?

Triage

FCPs

11 rust-lang/rust T-libs-api FCPs

  • merge rust.tf/80437 Tracking Issue for `box_into_inner` - (1 checkboxes left)
  • merge rust.tf/141574 impl `Default` for `array::IntoIter` - (3 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/140005 Set MSG_NOSIGNAL for UnixStream - (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)

dtolnay (1), Amanieu (4), jackh726 (1), joshtriplett (7), scottmcm (1), m-ou-se (8), nikomatsakis (2), compiler-errors (1), BurntSushi (7), the8472 (1)

(nominated) rust.tf/libs514 Add `Rwlock` `try_upgrade` method

Discussed last week, unnominating.

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

Defer, set up dedicated subset discussion to resolve?

Amanieu: Has been nominated for a while. need to have an in-depth discussion. separate meeting? inviting people outside the team?

JoshT: First half an hour conversation to discuss what we want. outside this meetings seems like a good idea.

Amanieu: Max 4 people to be productive. I'd like one of these people to be the rand maintainers.

Tomas: i can set up the meeting. At least 2 libs people.

  • rand maintainers
  • joshtriplett
  • Amanieu (optional)
  • TC
  • Mara (optional)

(nominated) rust.tf/133724 Tracking Issue for `breakpoint` feature (`core::arch::breakpoint`)

Discussed last week. Didn't finish conversation

FCP finished. bikeshedding?

JoshT: looks like there are no objections to the proposed functions. some discussion on core::arch::trap and something in core::hint, but those don't block arch::breakpoint.

TC: It seems like we're settled on the libs-api side for this. The intrinsic generated enough discussion on lang it'll need that FCP too, so the next step would be someone putting up the PR for this and nominating it for us.

JoshT to summarize discussion in a comment.

(nominated) rust.tf/140985 Change `core::iter::Fuse`'s `Default` impl to do what its docs say it does

Mara: Not just update the docs, rather than the behaviour?

David, Amanieu: new behaviour is better

Mara: When would it make a difference in practice?

?: Practically never.

FCP ongoing.

(nominated) rust.tf/141467 make `OsString::new` and `PathBuf::new` unstably const

Amanieu: same as Vec::new.

seems fine.

David: why not go to stably const right away?

Josh: we can r+ this and then start FCP for stable right after

(waiting on team) rust.tf/136687 Improve the documentation of `Display` and `FromStr`, and their interactions

Amanieu: we need to schedule a meeting for this

JoshT: we (amanieu+josht) should discuss this together and come back to the team with a proposal

Amanieu: summary: if a type implements both Display (and therefore ToString) and FromStr. Is there a default assumption that the output of Display can be passed back to FromStr? Not necessarily roundtrip, but at least parse.

JoshT: but also, to what extend do we recommend people implement it that way. do we suggest that it is 'more correct'. or just document that it might surprise people if you don't.

JoshT: I'd like us to document that it might be surprising if these do not round-trip, but we shouldn't go further and make a normative statement, especially so long after the fact.

Amanieu: I'd prefer that we go further and normatively suggest that the output of to_string should be at least accepted by FromStr and parse without error, even if these do not round-trip fully i.e. it could be lossy.

Amanieu/JoshT: We both agree that the documentation could be improved.

David: It might help if you both could boil this down to a set of invariants. That's what I'd want out of this meeting, and then the rest of us can weigh in on whether those invariants are reasonable or not.

The 8472: We'd need to look at the ecosystem here. If most people already support this round trip, that's one thing. It's another if that's not true, and many people would then have to document that. It'd be good to have data here.

Mara: We could open a E-help-wanted issue to ask for help.

Josh and Amanieu to have a follow-up meeting.

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

(new change proposal) rust.tf/libs597 Add trim_prefix and trim_suffix methods to str

short for:

  • s.strip_prefix(..).unwrap_or(s);, and
  • s.strip_suffix(..).unwrap_or(s);

David: clearer name might be 'trim_start_match_once' or something

David: trim_start_matches already has a plural in the name. could be trim_start_match.

Mara: We don't use the word 'match' for any of the other string pattern functions (replace, strip_prefix, etc.).

TC: What's our system with respect to "prefix" vs "start"? We have strip_prefix and also trim_start_matches.

Josh: we used to have trim_left and trim_right were deprecated (around 1.30)

Amanieu: "matches" is not a plural but a verb (it "matches" the pattern)

JoshT: so "trim_start_match" (singular) would be unclear given the meaning above

JoshT: our fallabck position: tell people to use strip_prefix followed by unwrap_or

Mara: I think we should have this function. i more often see strip_prefix().unwrap_or() than without unwrap_or.

Amanieu: Was strip_prefix returning an Option a mistake?

Mara: No! super useful while parsing.

JoshT: write a quick summary saying: we see enough usage to think they should exist. Got hang up by naming given all the other optiions that already exist. We're open to it if there's a good clear proposal for the names

TC: Adding to what Josh said, we're looking for someone to do an analysis of going through the existing names, find out what the right name is to be consistent and clear from the existing objections.

JoshT to summarize.

(new change proposal) rust.tf/libs596 paid

Spam. Closed.

(new change proposal) rust.tf/libs595 (My API Change Proposal)

Spam. Closed.

(new change proposal) rust.tf/libs594 Add more helpers for `Future`

Nominated for async

(new change proposal) rust.tf/libs591 ACP: `process::resolve_exe` and `Command::resolve_in_parent_path`

Chris Denton: Should we have a free function to search the command exe or somethingh in Command? Should we return the absolute path?

Amanieu: we have something that gives you the path from the env var?

Chris wants to give users some control over the path that's returned?

JoshT: on the one hand, this is useful. Q: is this portable or Windows-only? (A: portable)

JoshT: hesitant that we have our own implementation on path search for every OS. Having this means we must implement our own path search everywhere

Mara: not sure if we should expect every single resolved executable to be expressable as a (absolute) PahtBuf on all platforms. prefer the alternative mentioned in the parent FCP (resolve in parent path?)

TC: Do we have any of these platforms?

JoshT: In Fuchsia you should be able to run the functions as proposed; not clear if you want to run the OS functions.

Amanieu: Windows will add the ".exe" suffix the path resolution argorithm is path-specific

Mara: can't you get into a sitouation where the '.exe' is added twice?

Amanieu: motivation for "resolve exe" is (tomas: sorry missed this)

Mara: For Command, we can add more options about resolution to the builder. For resolve_exe, we can't add any options like that.

JoshT: we should document if there's an issue with time of check vs. time of use.

TC: The pattern you'd use is that you'd resolve it and then pass the fully-qualified resolution into Command.

JoshT: we should document this through

TC: One option, to address Mara's concern about how to extend this, we could use the Command builder, and add a method that would spit out the path that would execute it (without executing the command)

The 8472: might not work on unix with chroot before exec hook

JoshT: if you're on unix on chroot, and resolve /bin/sh do you expect "/bin/sh" or "chroot/bin/sh"?

The 8472: just saying the builder pattern is not magic and could give you wrong result (when calling outside the chroot e.g.)

Amanieu: We can discuss this at the second half of the meeting (in 1h).

(The first part of the meetin ended here.)


(The second part of the meeting started here.)

Amanieu: We should talk about each of the functions separately. resolve_in_parent_path would be useful.

Amanieu: We'll need to get an answer to the chroot question.

JoshT: We can say "if you have set before-exec or pre-exec we can always error out". And if you path an env var / chroot / similar, we can take those into an account during resolution.

The 8472: root permissions? We can do the resolution either as a parent or a child.

Amanieu: The way Command resolves the path doesn't do any fs access, just passes a bunch of paths to execv?

The 8472: If we add these methods, they could be interpreted to do whatever the parent would do to find the file.

JoshT: You could get a different answer by resolving as root or user (since a path could be inaccessible).

Chris Denton: Is this an issue we have currently?

JoshT: Only if we resolved the path ourselves rather than letting the OS do it.

JoshT: If we say we only do it in the parent, that's something we can reliably do, but it's less useful?

JoshT: If you're setting .UID, .GID, pre-exec etc. the match would be different.

TC: Can we document when things won't necessarily match the OS resolution?

JoshT: Agrees, we could provide detailed docs saying chroot works, if you do pre-exec, etc. it will fail (context: resolve_exe)

Amanieu: resolve_exe is a free function.

TC: But we could make it another command that works on the builder.

Amanieu: Doesn't think that's necessary. Document: "once you've resolved the path, pass this as an absolute path avoiding any resolition."

The 8472: We could make it a constuctor for Command. Do we need a free function?

Amanieu: resolve_exe should be fine and then just pass the absolute path to Command

Amanieu: resolve_exe would use the access system call

TC: The method on command would do exactly what resolve_exe would do.

JoshT: You set up a Command. You call a function on the command, you get ioresult PathBug that give you what you'd execute.

Amanieu: That's not enough. The access call can give you a different result.

JoshT: You could take the resolting pathbuf and pass it as the command to be executed.

TC: You could have a method that does just that. Feeds it back into the builder (use exactly what was resolve here) and then execute that.

The 8472: suggests making it a constructor method that resolves this at the build time.

Amanieu: That's what the free function is doing. You call resolve_exe, get an absolute path, pass it to Command::new

The 8472: We don't typically prefer free functions. The purpose of tihs is to prepare a command and executing it.

Amanieu: Last time we discussed it, there were reasons to do keep it as a free function.

TC+Josh: This is a new thread of discussion, having this in the builder would be useful.

Chris Denton + TC: Can we start putting things into nightly and let people experiment? See use cases.

Amanieu: Thinks as written this is fine.

TC: But Mara thinks this should be in a builder.

JoshT: Do we want to take into account any other options that are on Command? It's not just the PATH env. But also things like chroot, are you affecting the resolution in any other way. Mara's point was: free function is unextendable, Command is extendable.

The 8472: Different platforms might need different things. WASI was maybe something that might show up here.

Amanieu: WASI doesn't have exec.

The 8472: There was an OS (Fuchsia) that does something different here? Having a free function is less flexible than Command having the context (and could be extended in the future).

TC: Try it on nightly and you'll see. Might shift you views.

Amanieu: Maybe. Doesn't feel too strongly abouth this. Also doesn't think it's worth spending a half-an-hour on.

Summary: We were split on putting it into command or a free function. Would like to see experimentation on nightly to see what the correct/ergonomic approach would be. And sort it out during resolution.

TC: Are people ok with the resolve_exe name? That suggests Windows.

The 8472: we have precedent ("current_exe")

JoshT: Be happy to bikeshed, but the precedent is there.

TC: Agree.

JoshT: A lot of this back-and-forth was about resolve_exe. What about the resolve_in_parent_path

Amanieu: It's useful, would allow us to use posix spawn. We don't resolve anything, we just concatenate the path and try execing it.

(new change proposal) rust.tf/libs589 `ptr::fn_code_ptr` for explicitly getting an opaque pointer of a function

Amanieu: Were thinking about adding it to the FnPtr trait. But we don't actually need it there, we can add them as methods instead.

TC: Add them as methods or keep the trait methods unstable?

Amanieu: Either is fine.

TC: Any blockers to stabilise in FnPtr?

Amanieu: FnPtr seems only implemented for function pointers not function items. We want this method to work on function items too though. More work.

#![feature(fn_ptr_trait)]
use std::marker::FnPtr;
fn foo() {}

fn main() {dbg!(foo.addr());
}

error[E0599]: no method named addr found for fn item fn() {foo} in the current scope

TC: It does seem that there should be a trait that reperesents either a function pointer or function item.

Amanieu: Coercible to function pointer.

Amanieu: Are enum variant constructors affected too?

Amanieu: This ACP needs more discussion. Skip to the next meeting. Amanieu will reply.

(new change proposal) rust.tf/libs587 ACP: `try_exact_div` method on `NonZero<{integer}>`

Amanieu: Last time (2 weeks ago) Amanieu said this is too niche for the standard library.

TC: If we have a method that's worthwhile, then the bar for adding a try_ version for it is pretty low.

The 8472: This does something different: it's not returning an Option but a Result.

JoshT: The name seems reasonable. Are we happy with the signature?

Amanieu: The name doesn't seem reasonable. Not consistent with other try_ uses.

JoshT: The error case is different. This method divides a NonZero by NonZero there are different errors that can happen.

Amanieu: It's only implemented in unsigned numbers.

JoshT: The modulo for signed can be defined in multiple ways.

The 8472: The naming scheme is problematic.

TC: Not happy with our naming scheme you can have multiple error cases, to get consistent, you could get thins like: "unched_try_exact_if" etc. Multiple dimensions here cumbersome to represent as names.

The 8472: We can call it exact_div_or_rem.

Amanieu + TC: That would be ok.

Amanieu: Would we want this same method on main integer types as well?

The 8472: We could return a NonZero in the error case.

JoshT: In the error case yes, not in the exact case.

Amanieu: Would like to see the table for all the exact_div methods and types. Would like the whole picture to be consistent.

TC: On the lang team sometimes they see a small proposal and say "we want the bigger proposal". If we want that, we need to ask for it explicitly goes against people's natural inclinations.

Tomas: Will communicate this. Request for the people asking this: Between main integer types, nonzero, signed and unsigned. And exact_div_or_rem as the name.

(new change proposal) rust.tf/libs585 ACP: efficient runtime checking of multiple target features

JoshT: More efficiently check more than one feature at once if possible. The most obvious change: allow multiple arguments to "is x86_64 detected".

TC: Agree.

Amanieu: In a lot of cases you're selecting between multiple implementations of a function. You'll want to do several separate feature checks. This won't solve that as it stands. What would solve it is an API that returns a struct with the feature checks results.

JoshT: Agree. But the "and" usecase is worth solving now. That's what the FCP suggests.

Amanieu: Do we want to solve and or also or and others.

JoshT: In general we want to solve and and or. And also resolve type safety issues. But there are design decisions to be made here.

The 8472: We might need an or for RISC-V: some feature is available for "is this flag set or that flag set".

TC: There's an issue with the syntax: the Option 1 is unclear whether that's an and or or.

Amanieu: Can we use a boolean operator (e.g. && / ||). Also allows nesting and brackets.

JoshT: Agrees.

JoshT: We can require to enable a Rust feature to allow the macro to call an unstable function.

JoshT: Will summarise this in the issue.

TC: It sounds like we're aligned around 1) that we want what Amanieu described, in terms of a later and bigger type-based system for this, and also 2) that we want something here that's built in to this macro with && and || and whatnot.

Amanieu: Sounds right.

JoshT: Right now this detects strings. If we're intending to support boolean operators, do we want them to be applied to things that look like strings or remove the quotes?

Amanieu + The 8472: Some of them have dashes

JoshT: I withdraw the suggestion.

Amanieu: There's also going to be a problem for type based resolutions.

(new change proposal) rust.tf/libs584 `From<PipeReader> for File` and `From<PipeWriter> for File`

Josh: Seems reasonable. I think we should accept this.

The 8472: Is this unix only?

Amanieu: Not on Windows, but portable otherwise.

The 8472: We're committing to supporting it on all platforms. So non-Unix or non-Windows might be a problem.

JoshT: there's impl from OwnedFd for File.

The 8472: Currently guaranteed to be anything unix or Windows. Other platforms can be a problem.

JoshT: Fair point. Should work on any platform that's either Windows or unix. Is there a platform that's neither and its pipes are not files?

The 8472: Pipes and Files can be different OS types and have different APIs.

Amanieu: I think risk is minimal.

JoshT: The reason we didn't have this fully generic is there are file-like things we can't convert on Windows. Handles and Sockets are different things.

The 8472: This seems to be moving away from the current distinction we have.

JoshT: This is a convenient feature. I'm convinced by 8472's hesitation. This is not a really pressing issue. Writing the extra code is annoying (notably because it's target-specific), but that's it.

Amanieu: I'm in favour of this.

The 8472: This is the first impl that doesn't use OwnedFd.

JoshT: There's one other impl family that does that: you can get many thins from StdIo.

The 8472: But there you have to pass it into a process and the process can then reject it.

JoshT: The previous guarantee we made was you can convert a file or a pipe into StdIo. We didn't make a guarantee you can convert the pipe to a file

The 8472: This method is infallible.

JoshT: Any objections on adding a TryFrom impl?

Amanieu: I think such platforms are unlikely to ever appear. Even on Fuchsia they have a file descriptor emulation layer.

JoshT: UEFI doesn't really have simultaneous execution or threading. A pipe isn't a thing because you can't do preemptive multi threading?

JoshT: Seems like there are 2 options here:

  1. commit to always being possible to convert to a pipe on any platform
  2. make it fallible conversion

JoshT: If we did an FCP on the fallible approach, are there concerns from this group?

The 8472: We've already said all the OSes must have pipes (or return an error).

Amanieu: If you're pretending to be unix the pipe must be backed by a FD.

JoshT: What platforms do we have that aren't unix or Windows?

JoshT: Does VxWorks claim to be unix?

Amanieu: Yes it does! QNX claims to be unix, L4R3. Searching for "unix" in compiler's rustc targets. Fuchsia claims to be unix.

The 8472: What's TEEOS? Is that unix?

Amanieu: Trusted execution environmens OS.

(what follows is a long list of platforms claiming to be unix)

The 8472: TEEOS doesn't seem to be unix.

Amanieu: UEFI is non-unix non-windows.

Amanieu: The answer is: no, we don't make this guarantee (that pipes are backed by the same object as the file).

The 8472 to reply.

JoshT: Doesn't object to the conclusion. Didn't occur to him that we'd be committing to everything being unix and have pipes.

TC: Does it still make sense to have methods rather than From / TryFrom impl?

JoshT: By that point you've removed a lot of convenience.

JoshT: We could say: We're committing to the idea that whatever you're calling a pipe must be convertible to a file. Otherwise it's not a pipe.

The 8472: The primary usecase for PipeReader and Writer for creating processes. This is portable. Saying these can't be pipes just because this convenience method feels wrong. You're sacrificing the primary usecase on the altar of convenience.

Amanieu: Anything sufficiently complex for passing data between subprocesses will have some sort of handle. But we can't guarantee this on every (possible future) platform.

JoshT: Anyone making a new OS will have to have a posix emulation layer even if they're doing something different (better?) underneath.

JoshT: You could have a portable (NonFilePipeReader) type that's not convertible to files.

The 8472: That wouldn't work on anything that's expecting PipedReader as an argument.

Amanieu: We clearly don't have consensus so we should reject this.

No objections.

The 8472 will reply to the proposal.

(new change proposal) rust.tf/libs583 `Vec::into_chunks` to reverse `Vec::into_flattened`

Amanieu: I kind of like this.

The 8472: It does need to call into the allocator. You're relying on the allocator doing the right thing which isn't guaranteed.

Amanieu: In most cases in practice (which is what we should optimize for) we don't need to do any resizing.

The 8472: The capacity doesn't know what the user requested vs. what the allocator

Amanieu: Isn't as_chunks sufficient?

The 8472: They need an owned version.

JoshT: They take e.g. a long list of f32 and turn into a chunks of 3 f32.

Amanieu + The 8472: We only do this optimization with the exact match on the alignment.

Amanieu: We have as_chunks for slices, having into_chunks as Vec seems fine.

The 8472: The allocator doesn't guarantee that this won't ever do copying.

Amanieu: The implementation seems corret.

JoshT: Why does it need to reallocate here? If there is remainder, why can't we use the remainder for capacity?

Amanieu: Because capacity is not in bytes (it's in the item counts?).

Amanieu and JoshT: ok with this.

Amanieu will reply.

(stalled change proposal) rust.tf/libs124 Integrate `Error` trait with panic interfaces

Amanieu: When you do .unwrap() then it produces an error trait.

JoshT: It's storing an optional error in panic info.

JoshT: Under what circumstances would this work? Any time the error is static.

Amanieu: In the panic hook it stores the source of the error.

Amanieu: I don't think it's possible to make it work.

The 8472: The compiler magic might be able to?

Amanieu: No because specialization.

Amanieu: I don't think we can get away even at the edition boundary to change unwrap/expect to require error types. That would break so much of the ecosystem.

JoshT: You could keep unwrap as is, add unwrap_source which works if it's an Error and 'static.

Amanieu: Not clear that that provides enough value though.

The 8472: We can say specialization is not currently powerful enough. Will likely take a very long time.

TC: All major type system proposal have been off the table until the next trait solver is ready. Seems like it's getting close though.

The 8472: Suspects this will open the floodgates with all the pending type system stuff.

TC: Why does this need specialization?

The 8472: We want to optionally have a different behaviour in unwrap if something is an error type. Type-conditional behaviour.

TC: Looks like this isn't really an ACP, it's RFC-sized.

Summary: We can't do this without specialization or a change to the ecosystem that would break half the universe (change the bounds on unwrap to require Error instead of Debug). We could make it work with an edition-dependentant resolution, but it would still make a huge impact on the ecosystem.

TC: (wearing the edition hat): I don't want to pre-judge the solution, but this needs an RFC and think the migration through and specify all the details.

Consensus: Close.

TC: Can we do a small subset of this, leave some door open to them being able to get there?

Amanieu: Let's just leave this open and wait for a progress in the edition process that would let us move forward? Added S-blocked.

(stalled change proposal) rust.tf/libs344 ACP: Add `std::string::String::replace_and_count` and/or `replace_with`

Apparently already discussed last year.

JoshT: Mara responded that they can just use regex. And the original responder said they haven't realised regex would work for them. They realised it would. Sounds like this just needs closing?

TC: Having a replace_with method would be useful though?

Amanieu: At what point would you stop using stdlib and switch to regex?

TC: Basically never. Mostly uses this while parsing and at that point just use whatever's in the standard library.

Amanieu: replace_with would work.

The 8472: Any reason not to close it if regex works for them?

TC: replace_with is still a reasonable addition? (And reject the other two.)

JoshT: Do we have a reasonable justification to add it to the standard library since the proposer no longer does?

TC: Written it by hand already. Is that justification enough? Useful for writing parsers.

We're out of time: someone should post a signature for replace_with.

(The meeting ended here.)

(stalled change proposal) rust.tf/libs347 Context reactor hook

Josh: Large; underlying problem is important but it's not obvious that the proposed approach is close to the right solution.

Josh: Proposal: close, in favor of design work by wg-async?

(stalled change proposal) rust.tf/libs371 ACP: primitive numeric traits

(stalled change proposal) rust.tf/libs336 Add `or_try_*` variants for HashMap and BTreeMap Entry APIs

(stalled change proposal) rust.tf/libs194 Fix:Introduce an interface to expose the current `Command` captured env var logic

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

(stalled change proposal) rust.tf/libs453 Signed↔Unsigned integer methods

Josh: cast_signed and cast_unsigned are now stable as of Rust 1.87. Closed.

(stalled change proposal) rust.tf/libs133 Add fmt::Write to io::Write adapter

(stalled change proposal) rust.tf/libs379 Combine, an iterator adapter which statefully maps multiple input iterations to a single output iteration

Generated by fully-automatic-rust-libs-team-triage-meeting-agenda-generator