Commit Graph

80648 Commits

Author SHA1 Message Date
Liubov Dmitrieva
f9d35b55ae fix error handling in tcp reciever introduced by D43153574
Summary:
fix error handling in tcp reciever introduced by D43153574 (eefeafe420)

after D43153574 (eefeafe420) every incorrect input would terminate the tcp receiver and ? in
main function would terminate the CommitCloud WorkspaceSubscriberService.

As a result, we see the errors like these:

(https://streaming-graph.facebook.com/stream/commitcloud_live_updates?workspace=user%2Fliubovd%2Fdefault&repo_name=configerator%3D%3D&token_type=cat): error trying to connect: dns error: task 80 was cancelled. Continue...

#shipit

Reviewed By: sggutier

Differential Revision: D43623506

fbshipit-source-id: 8afc88b865b7346804eabec581cf833c148a9062
2023-02-27 12:20:41 -08:00
Muir Manders
8158d3d7da clone: reconcile rust and Python URL scheme handling
Summary:
Previously the Rust clone was disabled in Sapling mode since the Rust clone thought it could handle any URL scheme other than "file" and "ssh", but that wasn't true for https Git URLs, among others.

Invert Rust's logic to a supported list of schemes instead of unsupported schemes. In particular, support "mononoke" and eagerpo schemes "eager" and "test".

Reviewed By: quark-zju

Differential Revision: D43291978

fbshipit-source-id: 78656e0584c362aa9ae693535376f1026307e9ee
2023-02-27 10:32:57 -08:00
Muir Manders
bbfdcf24cb schemes: basic support for custom schemes in Rust
Summary:
Support resolving a given URL based on presence of custom "schemes" in config.

Kill special "fb" handling repo_name_from_url in favor of proper scheme support.

Reviewed By: quark-zju

Differential Revision: D43329356

fbshipit-source-id: 8f8cddcf2f77fdc9382e0d031ecb8d6cf4518d12
2023-02-27 10:32:57 -08:00
Liubov Dmitrieva
83e03754e3 use batch text fetching for fetching dates
Summary:
use batch text fetching for fetching dates rather than single revlog
edenapi requests in a loop

follow up for D43572943 (008e88081a)

#shipit

Reviewed By: RajivTS

Differential Revision: D43619158

fbshipit-source-id: b22df9df2fb298ff6e4113a81c6b3e163cd88175
2023-02-27 09:48:30 -08:00
Zhaolong Zhu
adeadd4793 copytrace: add CopyTrace trait
Summary: Add `CopyTrace` trait, these are the core APIs.

Reviewed By: quark-zju

Differential Revision: D43554313

fbshipit-source-id: d067650482151ae8073f030709ab0b929b0fd823
2023-02-27 07:42:35 -08:00
Zhaolong Zhu
da44cd90cd pathhisotry: add RenameTracer API
Summary: Added `RenameTracer` API, this will be similar to `PathHistory` excerpt that we will only care about file path (not the content id) when searching segmented changelog.

Reviewed By: quark-zju

Differential Revision: D43554314

fbshipit-source-id: ee4e7eb480750b982770631fc8d19e14c94d4c5b
2023-02-27 07:42:35 -08:00
Yan Soares Couto
a5535f73aa Make NextStep simpler
Summary:
By using "unboxed closures", we don't need to name the exact type of the output of a function, and here we only need it to be a future.

In this way, we can remove two of the type parameters of `NextStep` and make it simpler to use.

Reviewed By: Croohand

Differential Revision: D43503769

fbshipit-source-id: f1b66456c43e84dd4c77c500b684d5234237421c
2023-02-27 05:01:44 -08:00
Rajiv Sharma
486625c515 Allow open_managed_repos to open default repo-set in non-sharded mode
Summary: `open_managed_repos` method in `MononokeApp` opens the set of filtered and enabled repos for the given service. It also considers the deep-sharding status of the repos while opening them during initialization. If all the repos for the service are deep-sharded, then none of them will be opened during startup. This is desired when the service is running in sharded mode on TW, but not so when it is being run locally for testing. This diff adds a check to ensure that deep-sharding status is only considered if the service is executing in sharding mode.

Differential Revision: D43618886

fbshipit-source-id: 23ac5bcea7451f5e81ecb2dd74d61860bb3ef50f
2023-02-27 04:26:51 -08:00
Jan Mazur
4c2a52afbf make SCSC SM aware
Summary: I'm changing scsc to use shardmanager to talk to SCS. It will use `shardmanager:mononoke.scs` tier. For xrepo commands, we require to implicitly have all repos everywhere for nor as SM doesn't support shard colocation and the method requries repos to be colocated on a single host.

Reviewed By: RajivTS

Differential Revision: D38781575

fbshipit-source-id: 0dde8e3d0d96cd59c3eadf34e57b1ece8fdd9df5
2023-02-27 00:46:42 -08:00
Michael Cuevas
6b0134c35f Back out "add Python stub for prefetch-profile" and "[edenfs] kill python prefetch-profiles"
Summary: Some environments are still somehow using the Python version of edenfsctl even though they should be fully on the Rust version. That means some environments are experiencing failures due to `eden prefetch-profile` not being a valid command. This diff makes the Python version of edenfsctl available again to help fix this.

Reviewed By: fanzeyi

Differential Revision: D43589012

fbshipit-source-id: eb529b48bcadd734f80e809d2f7b41ef081d7442
2023-02-24 17:37:30 -08:00
Mark Shroyer
7b66e94f80 minitop: Quote Windows command line args
Summary:
Ensures binary names and command-line arguments in minitop on Windows are
quoted for clarity.  There isn't a win32 counterpart to CommandLineToArgvW
going in the opposite direction, so we implement the quoting algorithm
described by Microsoft.

Reviewed By: xavierd

Differential Revision: D43554024

fbshipit-source-id: 3745ce3d117d6e480273269c6464fd601b18ce8b
2023-02-24 17:21:01 -08:00
Mark Shroyer
8de61887bb Trim full path to binary from minitop
Summary:
On Windows, minitop should hide the absolute path to processes' binaries to make the process filename more visible.

There's a shlex crate that can parse Unix-like command lines, but I didn't see an equivalent for Windows. (The Unix command line grammar is different, and in particular shlex will eat unquoted backslashes that are legal on the Windows command line.) So here we use the `CommandLineToArgvW` win32 function to get the Windows equivalent.

After parsing the command line and stripping the full path from the executable name, for now we just naively join the arguments back together, which means binary names containing spaces won't be properly quoted. I may add this in a following diff.

Reviewed By: xavierd

Differential Revision: D43509750

fbshipit-source-id: d56535ded4984a8106f4a26dd5d1b54e2c60e297
2023-02-24 17:21:01 -08:00
Michael Cuevas
b36645215e redirect: use unmount force instead of eject
Reviewed By: mshroyer

Differential Revision: D43578518

fbshipit-source-id: 0e34b10bcc5651a4d41f5b7f63c2f4b1cf444258
2023-02-24 15:36:42 -08:00
generatedunixname89002005307016
7b32c8fbe7 Add annotations to eden/scm/edenscm/ext/drop.py
Reviewed By: quark-zju

Differential Revision: D43568485

fbshipit-source-id: a93b28fee6aa3a0b7b274ff0615727b3068839aa
2023-02-24 11:48:41 -08:00
Zhaolong Zhu
86e63feb16 pathhistory: update outdated doc
Summary: there is no `first` parameter in the API, deleted the corresponding comment.

Reviewed By: quark-zju

Differential Revision: D43554315

fbshipit-source-id: 62b6de2a885705bef3e1d410bc98c42792dcd7f3
2023-02-24 10:51:47 -08:00
Xavier Deguillard
91a7b93240 service: use getMountPoints instead of hand rolled version
Summary:
This function not only was hand-rolling getMountPoints, but it was also trying
to access the InodeMap and mount without testing if it was safe to do so.

Reviewed By: kmancini

Differential Revision: D43518655

fbshipit-source-id: 0a5551ce22952299a8464f3ca3e8f20b5514fa6d
2023-02-24 10:48:53 -08:00
Xavier Deguillard
166d3ce713 inodes: remove some unecessary getRootInode calls
Summary:
Calls to getRootInode are notoriously racy and tricky to get right. In some
places, it's trivial to replace them with arguments passed from the caller, who
already has a well known safe root inode.

Reviewed By: kmancini

Differential Revision: D43518656

fbshipit-source-id: d1ac7eee0f64500c6ad3c48dfb5fc9b32b835365
2023-02-24 10:48:53 -08:00
Xavier Deguillard
5793abfa0b service: add telemetry for working copy GC
Summary:
This will allow to better understand how many inodes were invalidated as well
as how long GC ran for.

Reviewed By: mshroyer

Differential Revision: D43199251

fbshipit-source-id: 5e598ba9ac02fe32b999284eba0baa7aa64d3770
2023-02-24 10:48:53 -08:00
Xavier Deguillard
c8726623a6 cli: run inode invalidation in the background in doctor
Summary:
Over the past few weeks, we discovered that invalidating the working copy
without looking at the atime of files can lead to undesirable behavior due to
races between invalidation and placeholders being laid on disk (D42694759 (f308c20680)). We
also learned that in some cases, invalidation can take a really long time in
cases where very large parts of the repository is loaded, during which `eden
doctor` is stuck waiting for the invalidation to complete.

To solve the first one, we simply need to have `eden doctor` pass a non-zero
age, in this case since atime's granularity is 1h, we use 1h as the age. For
the second one, the Thrift handler is modified to allow backgrounding the
invalidation and `eden doctor` uses this new flag.

Reviewed By: kmancini

Differential Revision: D42785599

fbshipit-source-id: 9d86686f791e124b016685e3669004338ca33359
2023-02-24 10:48:53 -08:00
Xavier Deguillard
4c7e1c5823 service: make EdenServer::getMountPoints safer
Summary:
In a few cases, the code wrongly assumes that the mount points returned by
getMountPoints will be safe to access even though it is documented (and
possible) that the mount will be shutdown after getMountPoints returns. To
prevent this, collecting the root inode with the mount point lock held is
necessary, thus the function now does exactly this.

Reviewed By: kmancini

Differential Revision: D43516295

fbshipit-source-id: a4bc48a60c187f1610e05803b06abdd8793533b3
2023-02-24 10:48:53 -08:00
Liubov Dmitrieva
008e88081a reduce number of revlog requests
Summary:
reduce number of revlog requests as much as possible

basically, make it no more than number of commit cloud bookmarks that point to
the known public nodes in the repo

the idea behind this diff is to check phases before calling any ctx = unfi[cloudnode], where the revlog request is made

Reviewed By: markbt

Differential Revision: D43572943

fbshipit-source-id: 6e3a30d651b6de3ff83a335bc203ba1206ab27d1
2023-02-24 10:18:05 -08:00
Saul Gutierrez
fe0db11be9 phrevset: support configerator
Summary: As title mentions

Reviewed By: quark-zju

Differential Revision: D43556258

fbshipit-source-id: 192f8dac6e32f0b1e57cad4f1dbb011ca8f76fb9
2023-02-24 09:46:26 -08:00
generatedunixname89002005367269
fb2d24a961 Daily arc lint --take BLACK
Reviewed By: zsol

Differential Revision: D43566530

fbshipit-source-id: 1398be613ae1533642de31d8b4ed34958005b08e
2023-02-24 09:23:00 -08:00
Liubov Dmitrieva
73599e28aa change order in revset
Summary:
change order in revset

in my repo the current version takes 167.76 sec (missing head len is 1 commit)
vs almost instant if I reoder

it is not only extremely slow but also does some remote requests

I checked other places and it seems draft() goes first in several other places,
so reorder here as well

Reviewed By: mzr

Differential Revision: D43568675

fbshipit-source-id: 2397f90f9cb8156250fb951d948ce710071349b2
2023-02-24 07:11:20 -08:00
Liubov Dmitrieva
4b6f3b77aa fix double calculation
Summary:
this line gets evaluated twice

```
<here in len>
    skipknowncheck = len(draftrevs) == len(missingheads)
<inside the function calculated again from scratch>
    newuploaded, failed = edenapi_upload.uploadhgchangesets(
        repo, draftrevs, force, skipknowncheck
    )
```

Reviewed By: markbt, mzr

Differential Revision: D43568570

fbshipit-source-id: 98bbad4c77a15da445fbde58b056ba86453568af
2023-02-24 07:11:20 -08:00
Jan Mazur
fade622e15 move encode/decode repo_name used in cmdlib/sharding to lightweight sharding_lib
Summary: I'm moving this out of executor_lib, so I can later include it in git-live-sync

Reviewed By: RajivTS

Differential Revision: D43561183

fbshipit-source-id: 5b2e28b919d33b5b00d814494fbaed2127baf42f
2023-02-24 05:54:46 -08:00
Liubov Dmitrieva
1282bded39 log from what version to what version the local state has been changed
Summary:
log from what version to what version the local state has been changed

this is nice for debugging, currently we don't log what the previous local
version was

Reviewed By: markbt

Differential Revision: D43568053

fbshipit-source-id: fee2baf6c2c47bb01b3185a91a983cedd367c990
2023-02-24 05:37:40 -08:00
Igor Makaruks
8060c8b86e - Restart Subscriptions Fix
Summary: This diff adds a timeot to `reqwest-eventsource` `poll` so that we could exit running tasks when `interrupt` has been set to `true`.

Reviewed By: liubov-dmitrieva

Differential Revision: D43534730

fbshipit-source-id: 0f924a5c669f31540acab29d549f55091cd02485
2023-02-24 00:42:32 -08:00
generatedunixname89002005307016
41541a3cc8 Add annotations to eden/scm/edenscm/commands/debugdirs.py
Reviewed By: quark-zju

Differential Revision: D43534378

fbshipit-source-id: 4ddcdb323ff6c7b87ce76e65895ed625a3cd3c9d
2023-02-23 19:15:34 -08:00
Jun Wu
6c19d99424 tests: add a way to track legacy repo formats in tests
Summary: This allows us to track how many tests are using legacy formats.

Reviewed By: sggutier

Differential Revision: D43546411

fbshipit-source-id: df0d711205ebc1d223c8f70cdbd65803bda4b3b9
2023-02-23 19:02:58 -08:00
Saul Gutierrez
b573755c02 make sl web work on dev mode
Summary:
[Some OSS users](https://github.com/facebook/sapling/issues/521) had some issues launching `hg web` after following the instructions we provide in the website.

This was caused by the command trying to launch the `../../edenscm-isl/isl` script, which only exists if `sl` is installed. If one compiled sl using something like `make oss`, it would instead be located at `../../../addons/isl`. This commit changes the prefix based on whether `sl` was compiled in dev mode or not.

Additionally, this makes `sl web` launch `isl` directly via node instead of using some of the two wrapper scripts created when building ISL.

Reviewed By: evangrayk

Differential Revision: D43288130

fbshipit-source-id: 2ff5e6f25fefe80213e2315bea5676bd55f93dcf
2023-02-23 17:31:01 -08:00
Xavier Deguillard
da64d926b5 store: preemptively write aux data to the LocalStore
Summary:
The Sapling backing store now provides both size and sha1 in the TreeEntry,
thus we can pre-compute the metadata and store it in the LocalStore to avoid a
roundtrip to the Saplig backing store when that metadata will be needed very
shortly.

Reviewed By: kmancini

Differential Revision: D43132760

fbshipit-source-id: 38dcba76d41e5801c8b716197af179543386df08
2023-02-23 17:00:41 -08:00
Michael Cuevas
714e5d1a9c avoid failing on startup when telemetry fails
Summary: Telemetry isn't strictly required when starting Eden, so let's not throw an exception when we fail to start our subprocess logger.

Reviewed By: xavierd

Differential Revision: D43544234

fbshipit-source-id: 36d5a538eb43b3fb880e047229cbfa4906d2796b
2023-02-23 13:45:33 -08:00
Evan Krause
2f9a6e0031 mapObject util
Summary: Add a small util for manipulating object types. This is useful if ever dealing with a type like `Record<MyEnum, SomeValue>`, it lets you do manipulations of the mapped type, with strong typing.

Reviewed By: quark-zju

Differential Revision: D43520828

fbshipit-source-id: feba922340253ef32ce4c03a9adb2ed58e3ad1f7
2023-02-23 13:19:40 -08:00
Evan Krause
fc4ee58788 Use VSCodeLink for ExternalLink
Summary:
Adjust the ExternalLink component to use `<VSCodeLink>` as the `<a>`. This gives us better styling of the <a> for free.

<ExternalLink> was only used in one place already, so this is easy to change

Reviewed By: quark-zju

Differential Revision: D43520829

fbshipit-source-id: bdf7cf460ffdd7c051b4061bce05f8c3c314bc09
2023-02-23 13:19:40 -08:00
Evan Krause
94a3dbcb8b VS Code extension v0.1.10
Summary:
Version bump and changelog entry for new OSS VS Code extension release.

I also delete the image from the VS Code README file. The problem is that this README is shown in two place, and the image link doesn't work in both at the same time:
1. When browsing the code in GitHub: https://github.com/facebook/sapling/tree/main/addons/vscode
2. When looking at the VS Code extension in the VS Code extension marketplace: https://marketplace.visualstudio.com/items?itemName=meta.sapling-scm

I think the VS Code extension description is slightly more important, but I also don't want to have a broken link in the github repo. So let's just remove the image altogether.

Reviewed By: quark-zju

Differential Revision: D43544130

fbshipit-source-id: 69519ef3236245b3a0b0bc8ee880ff84a607202d
2023-02-23 12:58:58 -08:00
Mark Shroyer
bb2a928f48 Update github workflow for parser->loader rename
Summary:
The crate was renamed in D42018937 (853cd5a192), so the workflow is failing:

https://github.com/facebook/sapling/actions/workflows/edenscm-libs.yml

Reviewed By: quark-zju

Differential Revision: D43544211

fbshipit-source-id: a1f6c06dc0b8c4463460afea22737c93c609bc95
2023-02-23 12:53:50 -08:00
Mark Juggurnauth-Thomas
fbe23f1b59 caching_ext: move spawn_memcache_writes determination into memcache handler
Summary: The `spawn_memcache_writes` feature used by changesets and the new commit graph should be part of the memcache handler, rather than externally implemented.  Essentially we want the real memcache handler to always spawn writes, however when dealing with mocks or no-ops, there is no need to spawn, and in fact spawning would be harmful by making the test less deterministic.

Differential Revision: D43410854

fbshipit-source-id: 0be62a4b49fcc0bd62aabba1d65d10f6d16e7129
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
3929956341 newfilenodes: use memcache handler for mocks and noops
Summary: The `newfilenodes` crate implements its own no-op and mock memcache handler.  Switch to using the memcache handler's versions.

Differential Revision: D43410857

fbshipit-source-id: adf973924fa70c33794eb02370a19a14317d4960
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
f6583ed36a newfilenodes: use cachelib handler
Summary: The `newfilenodes` crate implements its own mock cache, rather than using the common one via the cachelib handler.  Change to using the common one.

Differential Revision: D43410858

fbshipit-source-id: 915255a67dc545e7678a9283fb81ddbe1c820b55
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
df70f3e7a4 newfilenodes: use filenodes types for caching
Summary: The `newfilenodes` crate has wrappers around `FilenodeInfo` and `FilenodeRange`, however these are no longer necessary and can be removed.

Differential Revision: D43410859

fbshipit-source-id: 08171581f6fdda3b711aa0c04996c90231328710
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
d18bcf9903 filenodes: remove FilenodeRangeResult
Summary:
The `FilenodeRangeResult` type conflates two concepts: a range being too large, and the result of filenodes lookups being unavailable because filenodes are disabled.

Replace it with `FilenodeResult<FilenodeRange>`, keeping the notion of whether or not filenodes are disabled to `FilenodeResult`, and handling this concept always through that.

The type was also pointlessly generic.  It almost always contained `Vec<FilenodeInfo>`, except in a couple of places where that is easily removed, so remove the generic parameter.

Differential Revision: D43410852

fbshipit-source-id: 6be34555b8b56b72d2ea4b071fb03c64648e8406
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
50866019eb caching_ext: introduce noop-mode for cachelib and memcache caches
Summary: Sometimes we just don't want to cache at all.  Add a no-op mode so we can use the same code.

Differential Revision: D43410853

fbshipit-source-id: 20dd632df66dc85b4da18678ff56e5b83e987326
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
bab444d092 caching_ext: remove vestigial dead code allows
Summary: The Mock cache implementations are public, so they are never dead code.  Some methods are only used in the unit tests, but they can be marked as test-only, too.

Differential Revision: D43410856

fbshipit-source-id: a158b4b74e25537da9b2056cd272dd6c8cc07e18
2023-02-23 11:51:31 -08:00
Mark Juggurnauth-Thomas
44a0848f8a caching_ext: remove autoimpl from caching traits
Summary: This auto-impl is not necessary, as we can require a reference from all callers.  Removing auto-impl prevents accidental double references, e.g. if a caller called `fill_cache` with a reference, it would pass a double reference into `fill_caches_by_key`.

Differential Revision: D43269535

fbshipit-source-id: 91a4b77df0d62bb971f6fce72b917bcd3c9e0016
2023-02-23 11:51:31 -08:00
Mark Shroyer
33ba7d3fac Remove Cargo.lock on make clean (#534)
Summary:
[sapling] Remove Cargo.lock on `make clean`
The help text for `make clean` says:

> remove files created by other targets
> (except installed files or dist source tarball)

So I'd expect it to remove any non-installed built state like Cargo.toml.

Concretely, I was surprised by this behavior when the build failed after
pulling in updates, even after running `gmake clean`.  My Cargo.lock from a
previous build had pinned the watchman_client crate to an old version, but the
updated workingcopy crate relied on the addition of `BytesNameField` to
watchman_client@main.

I think it would be better if autocargo generated a Cargo.lock for us from the
Buck versions of dependencies, but as long as it's being generated as a build
artifact it should be removed by `make clean`.

Pull Request resolved: https://github.com/facebook/sapling/pull/534

Test Plan:
```
% cd eden/scm
% gmake oss
% ls Cargo.lock
Cargo.lock
% gmake clean
% ls Cargo.lock
% ls: Cargo.lock: No such file or directory
```

 ---
Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/sapling/pull/534).
* __->__ https://github.com/facebook/sapling/issues/534

Reviewed By: quark-zju

Differential Revision: D43478239

Pulled By: mshroyer

fbshipit-source-id: 2c472a0e1d86c85994191e242337dab8249bafaa
2023-02-23 11:19:12 -08:00
Pierre Chevalier
2a4d191a78 Fix clippy lint
Summary:
clippy complains with

```
non-binding `let` on a future
consider awaiting the future or dropping explicitly with `std::mem::drop`
for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_future
`#[warn(clippy::let_underscore_future)]` on by default
```

Because the future we are not awaiting comes from `tokio::spawn`, it is still executing. Use `std::mem::drop` to make the intent of ignoring the handle explicit while satisfying clippy.

Reviewed By: yancouto

Differential Revision: D43468794

fbshipit-source-id: 9da8fe940e00c3043fdfba7d25c8add94ca6818e
2023-02-23 09:48:42 -08:00
Rajiv Sharma
3e12d0d788 Add internal-only authorization check in upload_git_object endpoint
Summary: The `upload_git_object` endpoint and all other git-related endpoints are meant only for internal use. This diff adds an authorization check that prevents other users from using it.

Reviewed By: mitrandir77

Differential Revision: D43396144

fbshipit-source-id: e40ed319cb79988b42c4067c407c110ce8dde641
2023-02-23 09:30:04 -08:00
Rajiv Sharma
5ea4c7367e Implement upload_git_object method in SCS
Summary: As in title, this provides an SCS endpoint for uploading raw git objects except git blobs (since they would be uploaded via LFS). It also exposes the relevant error information in case the operation fails.

Differential Revision: D43395188

fbshipit-source-id: b83c5974ab47f2d29b63017801bca0ddb6215bf4
2023-02-23 09:30:04 -08:00
Jeremy Fitzhardinge
8dc7582f4b third-party/rust: remove memmap and migrate to memmap2
Summary:
`memmap` is unmaintained and hasn't been changed in over 4 years. `memmap2` is
a fork, which is regularly maintained.

Also bump dependency on `grep` as it removes the last third-party internal
reference to memmap.

Reviewed By: dtolnay

Differential Revision: D43486158

fbshipit-source-id: f763848bd295facf60ec601620afd68dfc655bea
2023-02-23 09:28:19 -08:00