Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pattern matching API to OsStr #109350

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Conversation

mina86
Copy link
Contributor

@mina86 mina86 commented Mar 19, 2023

cc @pitaj, @kennytm

This is a sizeable patchset so when reviewing looking at individual commits (rather than the whole changeset) is advisable.

The motivation for this PR is parsing command line arguments. It adds {starts,ends}_with, strip_{prefix,suffix}, {,r}split_once and split methods to OsStr supporting char, &str and FnMut(char) -> bool patterns. (Other methods can be easily added once general consensus for this PR is reached).

Note that this PR doesn’t implement RFC 2295 and doesn’t allow OsStr to be a pattern. This is done because:

  • in vast majority of cases this is not necessary,
  • OSStr indexing proposed in the RFC is complex to implement and error-prone to use and
  • this PR is forwards compatible with the RFC so if someone really needs &OsStr as a pattern it can be added at later time.

This PR also sort of implements the new Pattern API. As I understand it’s no longer a thing, but I’ve decided to keep the change in because it does allow common interface and code sharing. (Though I have some doubts about the actual interface; for example I question existence of Searcher::next method). Keep in mind this is just a means to an end so if messing about with core::str::pattern would be a blocker I can undo those changes.

The core idea with this PR is introduction of core::str_bytes::Bytes type which handles byte slices which are possibly invalid UTF-8. str and OsStr are kind of Bytes. With that, pattern matching has to be implemented only once for Bytes type so that the same matching code doesn’t have to be duplicated for str and OsStr. Bytes can have Flavours (UTF-8, WTF-8 or unstructured) which allow implementing optimisations based on str being valid UTF-8 or OsStr on Windows being valid WTF-8.

Commits present in this PR:

core: convert Pattern<'a> into Pattern
core: move Pattern et al to core::pattern module
Those two implement the Pattern API and convert str to use it. It’s really mostly just moving code around.
core: introduce internal core::pattern::{Split,SplitN} types
core: add core::pattern::EmptyNeedleSearcher internal type
Those two introduce helper types which help reuse code between str and OsStr implementations. Split is used in str::split and OsStr::split while EmptyNeedleSearcher is used to handle matching `""` pattern.
core: add try_next_code_point{,_reverse} internal functions
core: refactor tests/pattern.rs tests
Minor refactoring needed for future changes.
core: add internal core::str_bytes module handling string-like slices
core: add concept of Flavour to core::str_bytes
Implements Bytes type as described above and convert str pattern implementations to use it.
sys: reduce visibility of some internal OsStr-related types
Honestly I’m a bit confused why this is necessary.
std: add pattern matching to OsStr
Implements char and str patterns for OsStr and aforementioned matching methods. This also includes a demonstration test which shows how command line argument matching can be done with the provided interface.
core: add core::pattern::Predicate wrapper type
std: add predicate pattern support to OsStr
Implements FnMut(char) -> bool pattern for OsStr. This is done through a separate core::pattern::Predicate type because of orphan rules. I really don’t like this solution but I couldn’t figure out anything better.

PS. FYI, I have commits which converts core::slice::SlicePattern to the Pattern API implemented in this PR. Those aren’t included here since they would just distract from the actual changes but if someone is interested they can be found in pattern branch on my fork of the repository.

ACP: rust-lang/libs-team#311

@rustbot
Copy link
Collaborator

rustbot commented Mar 19, 2023

r? @joshtriplett

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Mar 19, 2023
@rustbot
Copy link
Collaborator

rustbot commented Mar 19, 2023

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@mina86
Copy link
Contributor Author

mina86 commented Mar 19, 2023

@rustbot label +T-libs-api

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Mar 19, 2023
@QuineDot
Copy link

CC #95290

CC rust-lang/libs-team#114

@apiraino
Copy link
Contributor

@QuineDot I infer your intent in this comment is to signal that this PR depends on that PR and the T-libs ACP, right?

I'll try to signal this with a:

@rustbot label s-waiting-on-acp -s-waiting-on-review

@rustbot rustbot added the S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. label Apr 25, 2023
@apiraino apiraino removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 25, 2023
@pitaj
Copy link
Contributor

pitaj commented Apr 25, 2023

@apiraino I believe their intention is that this PR supercedes those.

@rustbot label -S-waiting-on-ACP +S-waiting-on-review -T-rustdoc -T-compiler

@mina86 just a reminder that tests are currently failing

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. labels Apr 25, 2023
@mina86
Copy link
Contributor Author

mina86 commented Apr 26, 2023

@mina86 just a reminder that tests are currently failing

Unfortunately I don’t have Windows machine to run the tests so bare with me on those ones.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@mina86
Copy link
Contributor Author

mina86 commented Apr 28, 2023

 error: failed to run custom build command for `ahash v0.8.2`

No idea what the deal with this one is.

@rust-log-analyzer

This comment has been minimized.

@jmillikin
Copy link
Contributor

I'm also interested in this functionality (per the ACP linked above) so I tried to look into the build failure to help, but the size of this PR is much larger than I expected. It might be easier to debug the build failure if some of the deep refactoring could be separated out.

I've put the proposed implementation for my ACP into a PR at #111059, and with helper functions + docs + tests it's about 550 lines (~10% of this PR's net new LoC). It might be a good intermediate point, unblocking cross-platform flag parsing while the full details of how to reverse-split a OsStr get hammered out.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

mina86 added 8 commits May 5, 2023 21:58
Firstly, combine functions and results lists into a single list with
‘function => result’ pairs.  This makes it easier to match function
with its result.

Secondly, eliminate InRange step so that it’s easier to notice series
of matches or rejects.
Introduce a new core::str_bytes module with types and functions which
handle string-like bytes slices.  String-like means that they code
treats UTF-8 byte sequences as characters within such slices but
doesn’t assume that the slices are well-formed.

A `str` is trivially a bytes sequence that the module can handle but
so is OsStr (which is WTF-8 on Windows and unstructured bytes on
Unix).

Move bunch of code (most notably implementation of the two-way
string-matching algorithm) from core::str to core::str_bytes.

Note that this likely introduces regression in some of the str
function performance (since the new code cannot assume well-formed
UTF-8).  This is going to be rectified by following commit which will
make it again possible for the code to assume bytes format.  This is
not done in this commit to keep it smaller.
Since core::str_bytes module cannot assume byte slices it deals with
are well-formed UTF-8 (or even WTF-8), the code must be defensive and
accept invalid sequences.  This eliminates optimisations which would
be otherwise possible.

Introduce a `Flavour` trait which tags `Bytes` type with information
about the byte sequence.  For example, if a `Bytes` object is created
from `&str` it’s tagged with `Utf8` flavour which gives the code
freedom to assume data is well-formed UTF-8.

This brings back all the optimisations removed in previous commit.
I’m honestly not entirely sure why this is needed, but if I try to edit
the file in subsequent commit without this change I’m getting ‘missing
stability attribute’ errors:

    error: struct has missing stability attribute
      --> library/std/src/sys/unix/os_str.rs:22:1
       |
    22 | / pub struct Buf {
    23 | |     pub inner: Vec<u8>,
    24 | | }
       | |_^
Implement Haystack for &OsStr and Pattern<&OsStr> for &str, char and
Predicate.  Furthermore, add prefix/suffix matching/stripping and
splitting methods to OsStr type to make use of those patterns.

Using OsStr as a pattern is *not* implemented.  Neither is indexing
into OsStr.  All matching and indexing has to be done via provided
functions.
To work around orphan rules, introduce a wrapper type for predicate
functions to be used as pattern.  Specefically, if we want to add
predicat pattern implementation for OsStr type, doing it with a naked
`FnMut` results in compile-time errors:

    error[E0210]: type parameter `F` must be covered by another type when it
                  appears before the first local type (`OsStr`)
    impl<'hs, F: FnMut(char) -> bool> core::pattern::Pattern<&'hs OsStr> for F {
              ^ type parameter `F` must be covered by another type
                when it appears before the first local type (`OsStr`)
Due to technical limitations adding support for predicate as patterns
on OsStr slices must be done via core::pattern::Predicate wrapper type.
This isn’t ideal but for the time being it’s the best option I’ve came
up with.

The core of the issue (as I understand it) is that FnMut is a foreign
type in std crate where OsStr is defined.

Using predicate as a pattern on OsStr is the final piece which now
allows parsing command line arguments.
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-tools failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

---- compile_test stdout ----
diff of stderr:

-error: the function has a cognitive complexity of (28/25)
-  --> $DIR/cognitive_complexity.rs:6:4
error: test failed, to rerun pass `--test compile-test`
+  --> $DIR/cognitive_complexity.rs:327:13
    |
-LL | fn main() {
-LL | fn main() {
-   |    ^^^^
+LL |     let _ = Ok(42)?;
+   |             ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
    |
-   = help: you could split it up into multiple smaller functions
-   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`
-
-error: the function has a cognitive complexity of (7/1)
-  --> $DIR/cognitive_complexity.rs:91:4
+help: consider specifying the generic arguments
    |
-LL | fn kaboom() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
+LL |     let _ = Ok::<i32, E>(42)?;
 
 
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:149:4
-   |
-LL | fn baa() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
 
 
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:150:13
-   |
-LL |     let x = || match 99 {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:167:4
-LL | fn bar() {
-   |    ^^^
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:186:4
-LL | fn barr() {
-   |    ^^^^
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (3/1)
-  --> $DIR/cognitive_complexity.rs:196:4
-LL | fn barr2() {
-   |    ^^^^^
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:212:4
-   |
-LL | fn barrr() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (3/1)
-  --> $DIR/cognitive_complexity.rs:222:4
-   |
-LL | fn barrr2() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:238:4
-   |
-LL | fn barrrr() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (3/1)
-  --> $DIR/cognitive_complexity.rs:248:4
-   |
-LL | fn barrrr2() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:264:4
-LL | fn cake() {
-   |    ^^^^
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (4/1)
-  --> $DIR/cognitive_complexity.rs:274:8
-   |
-LL | pub fn read_file(input_path: &str) -> String {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:305:4
-   |
-LL | fn void(void: Void) {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (8/1)
-  --> $DIR/cognitive_complexity.rs:356:4
-   |
-LL | fn early_ret() -> i32 {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:377:13
-   |
-LL |     let x = |a: i32, b: i32| -> i32 {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:390:8
-   |
-LL |     fn moo(&self) {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:399:14
-LL |     async fn a() {
-   |              ^
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-
-error: the function has a cognitive complexity of (2/1)
-  --> $DIR/cognitive_complexity.rs:406:22
-   |
-LL |         pub async fn async_method() {
-   |
-   |
-   = help: you could split it up into multiple smaller functions
-error: aborting due to 19 previous errors
-
+For more information about this error, try `rustc --explain E0282`.
 
---
To only update this specific test, also pass `--test-args cognitive_complexity.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/clippy-driver" "tests/ui/cognitive_complexity.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/test/ui" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/test/ui/cognitive_complexity.stage-id" "-A" "unused" "--emit=metadata" "-Dwarnings" "-Zui-testing" "-L" "dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps" "-L" "dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/release/deps" "--extern" "clippy_lints=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libclippy_lints-48d2da227b3f9b72.rlib" "--extern" "clippy_utils=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libclippy_utils-bad1548ee8a3ddef.rlib" "--extern" "rustc_semver=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/librustc_semver-963bbd3f89834643.rlib" "--extern" "serde=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libserde-e22c295747291f5a.rlib" "--extern" "itertools=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libitertools-b6f83e8bf7b1d2e3.rlib" "--extern" "parking_lot=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libparking_lot-545a5b41a12a98e2.rlib" "--extern" "quote=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libquote-21e023f2887ebff8.rlib" "--extern" "syn=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libsyn-9936341359a757f2.rlib" "--extern" "derive_new=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/release/deps/libderive_new-37e0204bcdda2709.so" "--extern" "serde_derive=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/release/deps/libserde_derive-c7bacd82195bfecc.so" "--extern" "if_chain=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libif_chain-03f75cdc6d4d3afc.rlib" "--extern" "futures=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libfutures-99ea93d45a2253f6.rlib" "--extern" "tokio=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libtokio-e0524b7e2611e851.rlib" "--extern" "regex=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libregex-619ac20e364f2b2c.rlib" "--edition=2021" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/test/ui/cognitive_complexity.stage-id.aux"
------------------------------------------

------------------------------------------
stderr:
stderr:
------------------------------------------
{"message":"type annotations needed","code":{"code":"E0282","explanation":"The compiler could not infer a type and asked for a type annotation.\n\nErroneous code example:\n\n```compile_fail,E0282\nlet x = \"hello\".chars().rev().collect();\n```\n\nThis error indicates that type inference did not result in one unique possible\ntype, and extra information is required. In most cases this can be provided\nby adding a type annotation. Sometimes you need to specify a generic type\nparameter manually.\n\nA common example is the `collect` method on `Iterator`. It has a generic type\nparameter with a `FromIterator` bound, which for a `char` iterator is\nimplemented by `Vec` and `String` among others. Consider the following snippet\nthat reverses the characters of a string:\n\nIn the first code example, the compiler cannot infer what the type of `x` should\nbe: `Vec<char>` and `String` are both suitable candidates. To specify which type\nto use, you can use a type annotation on `x`:\n\n```\nlet x: Vec<char> = \"hello\".chars().rev().collect();\n```\n\nIt is not necessary to annotate the full type. Once the ambiguity is resolved,\nthe compiler can infer the rest:\n\n```\nlet x: Vec<_> = \"hello\".chars().rev().collect();\n```\n\nAnother way to provide the compiler with enough information, is to specify the\ngeneric type parameter:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<char>>();\n```\n\nAgain, you need not specify the full type if the compiler can infer it:\n\n```\nlet x = \"hello\".chars().rev().collect::<Vec<_>>();\n```\n\nApart from a method or function with a generic type parameter, this error can\noccur when a type parameter of a struct or trait cannot be inferred. In that\ncase it is not always possible to use a type annotation, because all candidates\nhave the same return type. For instance:\n\n```compile_fail,E0282\nstruct Foo<T> {\n    num: T,\n}\n\nimpl<T> Foo<T> {\n    fn bar() -> i32 {\n        0\n    }\n\n    fn baz() {\n        let number = Foo::bar();\n    }\n}\n```\n\nThis will fail because the compiler does not know which instance of `Foo` to\ncall `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error.\n"},"level":"error","spans":[{"file_name":"tests/ui/cognitive_complexity.rs","byte_start":6751,"byte_end":6753,"line_start":327,"line_end":327,"column_start":13,"column_end":15,"is_primary":true,"text":[{"text":"    let _ = Ok(42)?;","highlight_start":13,"highlight_end":15}],"label":"cannot infer type of the type parameter `E` declared on the enum `Result`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"consider specifying the generic arguments","code":null,"level":"help","spans":[{"file_name":"tests/ui/cognitive_complexity.rs","byte_start":6753,"byte_end":6753,"line_start":327,"line_end":327,"column_start":15,"column_end":15,"is_primary":true,"text":[{"text":"    let _ = Ok(42)?;","highlight_start":15,"highlight_end":15}],"label":null,"suggested_replacement":"::<i32, E>","suggestion_applicability":"HasPlaceholders","expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0282]: type annotations needed\n  --> tests/ui/cognitive_complexity.rs:327:13\n   |\nLL |     let _ = Ok(42)?;\n   |             ^^ cannot infer type of the type parameter `E` declared on the enum `Result`\n   |\nhelp: consider specifying the generic arguments\n   |\nLL |     let _ = Ok::<i32, E>(42)?;\n   |               ++++++++++\n\n"}
{"message":"For more information about this error, try `rustc --explain E0282`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0282`.\n"}

------------------------------------------

@Dylan-DPC
Copy link
Member

@mina86 any updates on the CI failure?

@mina86
Copy link
Contributor Author

mina86 commented Jun 1, 2023

Sorry, no, didn’t really have much time to look into it closely. Having said that, this is ready for high-level review even with failing tests. I would rather not spend time fixing tests if the end decision is that this is a completely wrong approach.

@bors
Copy link
Contributor

bors commented Jul 8, 2023

☔ The latest upstream changes (presumably #113491) made this pull request unmergeable. Please resolve the merge conflicts.

@tgross35
Copy link
Contributor

I have nothing useful to add here, but need to say I love the kernel-style per-commit-reviewable patchset with actually useful commit messages. This repo needs more of that!

@Dylan-DPC
Copy link
Member

@mina86 any updates on this?

@mina86
Copy link
Contributor Author

mina86 commented Oct 20, 2023

@mina86 any updates on this?

I’m waiting for a reviewer to take a look at this before I commit more time to fixing all the CI failures.

@epage
Copy link
Contributor

epage commented Dec 7, 2023

Thank you for your work on this! I was wondering why we never did this and then I found your PR!

In hopes that this will help move this along, I've created an ACP for this (rust-lang/libs-team#311).

@epage
Copy link
Contributor

epage commented Dec 19, 2023

@mina86 libs-api has gotten back about what is needed for moving this forward, see rust-lang/libs-team#311

@Dylan-DPC Dylan-DPC added S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 8, 2024
@joshtriplett
Copy link
Member

r? libs-api

@rustbot rustbot assigned dtolnay and unassigned joshtriplett Feb 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.