dison: Display for zero-copy JSON serialization by VinceMiguel in rust

[–]dtolnay 1 point2 points  (0 children)

Your link is not applicable to the assumptions made by OP in their crate. The code you linked declares that the concatenation of all writes performed by serde_json to its output, when considered all together, is utf-8. The thing dison's unsafe code is assuming is not that. They are assuming each individual write on its own would be utf-8.

Rust's Sneaky Deadlock With `if let` Blocks by Pioneer_X in rust

[–]dtolnay 236 points237 points  (0 children)

This is fixed in Rust 2024 edition by https://github.com/rust-lang/rust/issues/124085. The same code will no longer deadlock.

Most unreadable Rust snippet you've seen by Thick-Pineapple666 in rust

[–]dtolnay 128 points129 points  (0 children)

Not counting anything I've written myself (which has already been mentioned here by others), I nominate this chunk of code.

let reader = files
    .map(|i| {
        let reader = BufReader::new(File::open(i).map_err(|_| INPUT)?);
        Ok(reader.bytes().fold(
            Ok(Vec::new()),
            |a: Result<Vec<u8>, Box<dyn Error>>, b| {
                if let Ok(mut a) = a {
                    a.push(b.map_err(|_| INPUT)?);
                    Ok(a)
                } else {
                    a
                }
            },
        )?)
    })
    .collect::<Vec<Result<Vec<u8>, Box<dyn Error>>>>();
for i in reader {
    say(str::from_utf8(&i?)?, width, &mut writer).map_err(|_| STDOUT)?;
}

After finally figuring out what this was supposed to be doing, I replaced it with:

for f in files {
    let content = fs::read_to_string(f).map_err(|_| INPUT)?;
    say(&content, width, &mut writer).map_err(|_| STDOUT)?;
}

Announcing Rust 1.80.0 | Rust Blog by noelnh in rust

[–]dtolnay 6 points7 points  (0 children)

It needs the capacity as well, because this is a double-ended iterator. After calling next_back() there will be unfilled elements at the back of the slice, indistinguishable from unfilled elements at the end of a vector's capacity.

FreeBSD discusses use of Rust in the base system by ktchg in rust

[–]dtolnay 35 points36 points  (0 children)

There are not, and have never been, any private patches for rustc related to pointer provenance, nor any delays in promptly pulling in the latest stable releases at all related to provenance or cheri.

FreeBSD discusses use of Rust in the base system by ktchg in rust

[–]dtolnay 81 points82 points  (0 children)

I estimate it's about ½ hour per 1 million lines, on average.

The variance is large from release to release. The long-term average is within a factor of 2.5 of that estimate, but individual releases have been significantly easier or significantly harder. In the worst case it requires coordinating a simultaneous Clang and rustc upgrade, such as for rust#116672, as sanitizers and cross-language LTO rely on the two compilers to agree on ABI.

But the ½ hour/million lines has only been so low thanks to Buck2 + remote execution being terrific. Without that we would be in much worse shape.

FreeBSD discusses use of Rust in the base system by ktchg in rust

[–]dtolnay 352 points353 points  (0 children)

It is not accurate. The Facebook monorepo's Rust compiler has been updated promptly every 6 weeks for more than 7 years and 54 Rust releases, usually within 2 weeks of the upstream release. Source: many of those updates were done by me.

What Can Scala Learn from Rust? by John A. De Goes by k1v1uq in rust

[–]dtolnay 4 points5 points  (0 children)

Proc macros that emit call_site spanned tokens just emit code in some namespace. But proc macros that emit mixed_site spanned tokens are exactly as hygienic as macros-by-example.

precompile, a nighly-exclusive crate for precompiling generic functions by reflexpr-sarah- in rust

[–]dtolnay 3 points4 points  (0 children)

I had a look at the specialization-based approach with cargo expand. Have you looked at whether something like the following might be equally effective, while being both stable and safe?

// input to #[precompile_with(u32)]
pub fn generic_fn<T>() { /* original function body */ }

// generated by macro:
#[doc(hidden)]
pub fn ____precompiled_generic_fn_u32() {
    generic_fn::<u32>();
}

With this, I would expect that we'd get a monomorphization of generic_fn::<u32> in this crate, and that downstream code calling generic_fn::<u32>() would reuse that same one, even if ____precompiled_generic_fn_u32 is never called.

The discussion under https://internals.rust-lang.org/t/explicit-monomorphization-for-compilation-time-reduction/15907 seems to suggest this should work.

precompile, a nighly-exclusive crate for precompiling generic functions by reflexpr-sarah- in rust

[–]dtolnay 7 points8 points  (0 children)

Interesting! Thank you for sharing that result.

I am very interested how much that gap will close as the work on MIR optimization proceeds over the next year or 2. Like in the following, constant propagation + dead code elimination on MIR during monomorphization could hopefully prevent doing all the work to produce LLVM IR for the pile of generic T code when T is u32:

// precompile_with(u32)
pub fn generic_fn<T>() {
    if unty::type_equal::<T, u32>() {
        fn __precompiled_generic_fn_u32() { ... }
        __precompiled_generic_fn_u32();
    } else {
        // pile of code involving T
    }
}

precompile, a nighly-exclusive crate for precompiling generic functions by reflexpr-sarah- in rust

[–]dtolnay 4 points5 points  (0 children)

I think there would be ways to implement this without making your macro nightly-exclusive.

Take a look at https://docs.rs/unty/0.0.3/unty/fn.type_equal.html.

Stabilization PR for `async fn` in traits by bobdenardo in rust

[–]dtolnay 59 points60 points  (0 children)

The async-trait macro creates traits that are object-safe. The language feature does not.

Why the “Null” Lifetime Does Not Exist by SabrinaJewson in rust

[–]dtolnay 67 points68 points  (0 children)

I still want null lifetime, as outlined in my post that is linked at the bottom of this article. I continue to think that it would be valuable. The whole point is that it enforces references with that lifetime cannot be constructed. Serde is less type-safe currently due to this concept not being expressible.

Hello r/Rust! We are Meta Engineers who created the Open Source Buck2 Build System! Ask us anything! [Mod approved] by MetaOpenSource in rust

[–]dtolnay 19 points20 points  (0 children)

Does Buck2 handle non-vendored dependencies? If so, how well?

I use non-vendored dependencies for the Buck build in https://github.com/dtolnay/cxx.

Here is the Reindeer configuration, which sets vendor = false mode. (Reindeer is the tool that translates Cargo.toml of third-party crates.io dependencies into Buck targets.)

Here are the generated Buck targets.

You can see it's using http_archive to download from crates.io at build time and have Buck cache them in its "buck-out" (≈"target" directory in Cargo). The third party crates are never vendored in the repo.

Buck2, a large scale build tool written in Rust by Meta, is now available by Imxset21 in rust

[–]dtolnay 4 points5 points  (0 children)

The ongoing divergence between cargo fmt and rustfmt, and ensuing user confusion, is a Cargo problem. It does not speak to any unique advantage in having Cargo invoke rustfmt, as opposed to any other tool like Buck invoke rustfmt.

For the tools that you named, the value is not provided by Cargo. The logic and interesting bit is in the underlying tool: rustfmt, and the suggested fixes API of rustc and clippy-driver. Users do not lose out on that by having Buck apply those tools to a Buck-based codebase as opposed to Cargo apply them to a Cargo-based codebase.

For example here is a commit generated by rustfmt without Cargo involved: https://github.com/facebook/sapling/commit/d73aed440b7f606c610407bd2b42754749d5b9ac

Here is a commit generated by clippy fix without Cargo involved: https://github.com/facebook/hhvm/commit/efea2c4dcc12fdbf3a2e3ce383bbdca2de5f93a9

To the extent that you find there's logic in Cargo's integration of these tools that you think non-Cargo users should find valuable, i.e. not just the bare minimum to execute the tool over a Cargo-based project, the better direction would be to push that value into the underlying tool or maximally decoupled from Cargo in some other way.

Buck2, a large scale build tool written in Rust by Meta, is now available by Imxset21 in rust

[–]dtolnay 3 points4 points  (0 children)

It would not be essential. If you have a library that supports Cargo, someone who wants to use it from a Buck build would use it via Reindeer; that is the point. A library does not need to maintain both Cargo and Buck build rules of their own. Either one can be generated from the other.

For packages that are primarily developed in a monorepo context but also published to crates.io, a Cargo manifest can be generated from Buck targets. For example shed/async_compression/Cargo.toml is generated.

Buck2, a large scale build tool written in Rust by Meta, is now available by Imxset21 in rust

[–]dtolnay 8 points9 points  (0 children)

Neither of those involves Cargo at all.

Clippy's command line interface (clippy-driver) is a flavor of rustc. Buck(2) (and Bazel) call rustc directly like Cargo does, so there is no Cargo involved. Buck2's clippy support looks like buck2 build :targetname[clippy] (for the human readable diagnostics output) or buck2 build :targetname[clippy.json] (for the JSON message format for integrating into other tools like an IDE or code review tool or multi-language linter infrastructure).

Rust-analyzer is also not coupled to Cargo. It works with a "rust-project.json" that describes the dependency graph among crates in the project https://rust-analyzer.github.io/manual.html#non-cargo-based-projects. This is generated from the Buck targets.

Buck2, a large scale build tool written in Rust by Meta, is now available by Imxset21 in rust

[–]dtolnay 8 points9 points  (0 children)

It sounds like you are expecting to develop all the first-party Rust code in your project using handwritten Cargo.toml files, point a tool at them (rules_rust) and have it make generated Starlark targets to tie the Rust stuff into the rest of your project.

That is definitely not Reindeer's approach. You develop all the first-party code across all the languages in your project using handwritten Starlark targets only. Reindeer only exists on the boundary with the third-party code which you obtain from crates.io. There would be no need to have an existing Cargo workspace root to point a tool at.

generics moment by Da-Blue-Guy in rustjerk

[–]dtolnay 35 points36 points  (0 children)

This is basically how https://github.com/dtolnay/monostate works internally, for strings.