The video keeps triggering my sense of seeing CGI, but the hiding effect on display can absolutely be accomplished in camera.
6,196 karma · joined June 6, 2012
The video keeps triggering my sense of seeing CGI, but the hiding effect on display can absolutely be accomplished in camera.
fn needs_string_like(x: Into<String>) {
fn actual_logic(_: String) {}
actual_logic(x.into())
}
which is the explicit way of representing the same thing rustc would be doing automatically. The above will create an almost empty `needs_string_like` for each type that it is called with, but a single `actual_logic`. IIRC some optimization passess would completely remove specific instances of `needs_string_like` (like if you call `needs_string_like(String::new())`).A lot of those things are in different stages of being fixed. I would personally want the default for generated debug information to be changed. cargo gc will help with running out of disk space. Better cross-project reuse of existing rlibs could be accomplished with some better tracking of optional features that can be unified (think having `serde` with feature `derive` enabled in one project, and having it without it in another: features are supposed to be purely additive, so you could reuse the earlier rlib on the later, but in practice people (ab?)use features in non-additive ways so it isn't straighforward to do something like that by default). Tools like hakari lets you create workspace-unified Cargo.toml to emulate this behavior.
This is not quite true: the Foundation handles things like receiving and distributing some payments, helping conferences, employing people for operations (crates.io), and ownership of the trademark. But Rust the language and toolchain is managed by the people doing the work https://rust-lang.org/governance/
> It’s completely possible that Rust’s compiler contains a backdoor. And nobody would know. Now this last point is highly speculative and conspiratorial,
Yes.
> but I’m not the only one concerned about it.4 The only way to compile Rust’s compiler is using a binary package of the previous version released by the Rust Foundation.
Or using https://github.com/thepowersgang/mrustc. And it is not released by the Foundation.
> Since there exists only a single fully-functional, usable implementation of the Rust compiler, the Rust Foundation must be trusted.
> Considering its history, owners, and track record of issues with mismanagement,5
The linked to blogpost is about a fuck up that a subset of people in the project, who were responsible for RustConf, caused. The ones with leadership position stepped down from them out of their own volition. The Foundation in particular had absolutely nothing to do with the whole fiasco.
> I find it hard to trust it at all.
> My suggestion is: slow down. First, the community should focus on improving the Rust language itself instead of trying to “improve” other projects by rewriting them. I propose using that energy to help the GCC Front-End for Rust project6—an alternative compiler which would alleviate the concerns for the possible presence of a backdoor. Currently, it’s in an early phase of development.
Who is the OP talking to? Slow what down? Because there are people working on https://github.com/Rust-GCC/gccrs. I don't work on it, because I do what I do on my spare time and I find it more rewarding to improve the user experience of rustc itself, instead of implementing the same logic for the third time in a language I don't particularly enjoy. Others are equally disinclined to work on a C++ frontend implementation. The project certainly spends its time focused on improving the language. It is also hard to tell people in the Rust Project what to do: it is open source, it is a showupocracy. The people working on it are already at their limit on what responsibilities they can take on.
If the target audience of the blogpost is "the community", I also think it misses the mark. The "X rewritten in Rust" announcements I would see before LLMs would be the projects' own maintainers desiring to use Rust, and not external sources imposing it on others. There have been over enthusiastic people (and trolls) bothering projects in issue trackers and mailing lists, but I've never seen a level of volume commensurate to the meme's fame. (Nowadays I see vibe-coded projects done in Rust, but those are also not imposing their codebase on other existing projects beyond sucking up the air out of the room and making it annoying to read news aggregators due to high volume and low quality).
> And the people associated with Rust often don’t seem to have the best intentions in mind, or are just following a trend without thinking for themselves.
That's quite a view you have of people like myself and my colleagues. I have significant disagreements on how some facts and opinions are framed in the blogpost, but closing with stating that I and my colleagues in the project are ill intentioned and/or don't think for ourselves absolutely ensures that I won't be listening to anything else you have to say in the matter.
Back when Twitter was a thing I'd spend time searching for "negative Rust sentiment" because it was an excellent way of finding unpublished feature requests and real issues that needed to be addressed, after sieving through the less than productive way those real problems were presented with. This latter emotional labor was also the reason that it caused a round of burn out, until I realized that if something is A Problem, more than one person will ultimately hit it. Which means that if there are two people raising the same point, you don't need to waste your time engaging with the one being an asshole, and instead spend your time engaging with the one that will be productive.
> Employers must attest to the Department of Labor that they will pay wages to the H-1B nonimmigrant workers that are at least equal to the actual wage paid by the employer to other workers with similar experience and qualifications for the job in question, or the prevailing wage for the occupation in the area of intended employment – whichever is greater.
Some people propose relaxing this rule for "workspaces" (local projects with multiple crates that are not published individually). I haven't researched whether that would be technically feasible.
Wild improves things significantly, but it really depends on the kind of project. For some a third of the time can be linking. And not everyone configures their environment to use a different linker. Another thing that can easily improve performance is changing the global allocator, but I've seen teams that measured 10% perf improvements in their own metrics decide against going with anything other than the "default".
I fully expect that if wild delivers an effective incremental linking architecture, then rustc will be able to produce the patches directly (instead of wild having to produce patches from two versions of the object files), which would mean both that rustc is producing less LLVM bytecode and that wild gets to do what it (will) do best and make linking as fast as mechanically possible.
> This seems absolutely insane to me given how pervasive macros are in Rust
There was some work done on this front, but I haven't kept up to date on the current status of that. There was a PR showing promise https://github.com/rust-lang/rust/pull/129102 (later landed as https://github.com/rust-lang/rust/pull/145354, 10% on a specific serde-heavy crate, reports of 32% improvements in the original PR). The tracking issue doesn't have any updates https://github.com/rust-lang/rust/issues/151364, but you can try out nightly with -Zcache-proc-macros to see what the effect could be on your projects.
Part of the problem I see is that crates will have to opt-in (and we might be able to change the default over an edition boundary) to get the perf benefit, and it might require a granularity lower than "a crate" (which would complicate implementation). I haven't seen additional discussions around these design considerations (needed to stabilize), which will need to happen before people can see progress.
Sadly, Rust is, like many open source projects, a show-up-o-cracy: you need a motivated (group of?) individual(s) to deliver a feature to fruition, and if the person driving a feature is fine with using nightly for their purposes, and only needs a subset of a feature, they will drive the feature to that state (lets say 80% completion), and then the feature will linger (until someone else with enough motivation to see the other 80% through shows up). This is exacerbated because the project is unwilling to have 80% solutions on stable unless the state is very clearly not going to preclude other future work, or the path to completion is 100% visible (but if that were the case, then it would have been completed already). So we end up with situations like the Allocator APIs.
Some ideas to speed up compilation by not evaluating items that are not used might pan out significantly for big crates in your dep tree (that behavior might never be stable because that would allow items with compile errors in a crate that would still let your application compile, which is against the Rust approach). The same work to do that would also allow overlapping of crate evaluation between different rustc instances called by cargo, as it would require partial evaluation of crates (to do name res only and gather the symbols needed from its deps).
Another thing is that stable rust doesn't treat macros as idempotent (because that wasn't a requirement from the start, there are crates that do dynamic IO to generate types), but if they are then incr comp can be faster by not evaluating them unnecessarily.
I know people are working on a bunch of different strategies to improve both first and incremental compile times, and I'm looking forward to the fruit of their labor.
Compile times are rarely the bottleneck for me, but that doesn't mean I won't welcome any improvements on that front.
Few ideas are new under the Sun. But the inventor and the popularizer are rarely the same. We should be happy that the ideas got more exposure instead of litigating novelty.
You weren't kidding: it was exactly 4 years ago ("September 13, 2022").
This is not the only kind of breakage a project can experience. Trying to bring up an older project on a new platform will be a compile error (like building a project from 2018 on an Mx Mac), and updating the appropriate dependency to an appropriate version might become a chore. I have no idea how to improve the situation there to make that less painful, beyond having a simple database of crate-version+platform+rustc-version so that the toolchain could provide better/actionable messaging beyond "shit's broken".
When I talked with the people at AWS responsible for updating both the myriad Java compilers in use as well as Rust for every project in the company, they claimed that updating Rust was always painless and didn't even appear as a blip in their radars compared to other similarly wide reaching updates.
Calling Rust from C++ seems to be more technically straightforward than the reverse.
Then the conversation is about forward compatibility, whether developers should wait X amount of time before using new std APIs or features, and whether the ease of using rustup and project expectation of it being accessible is reasonable or not.
By raw population numbers, most people worldwide does live in large cities with a lot of coverage by some type of public transport, not necessarily trains or subways. Buses exist.
All the while all I could think was "you're spending your time making it more likely for a collision to happen, all to 'anger' a toaster with 360° camera coverage".
> That doesn't sound like much, but having hand-written plenty of recursive descent parsers, it's most of what you need for good error messages.
In my experience having access to the appropriate place where the parser failed is necessary but wholly insufficient for good diagnostics.
The Rust grammar is actually quite regular, that's why we have things like the turbofish for type parameters (`binding.method::<Type>()`): it makes the grammar unambiguous (a naïve parser would with a complicated grammar that accepts chained comparisons would have to deal with differentiating between `binding.method < value > ()` and `binding.method<Type>()`). But that doesn't mean the rustc parser doesn't do the work of supporting some the more complex grammar in order to provide better diagnostics. I like to say that rustc actually knows about meta-Rust, a daughter language that goes crazier in its features. I also joke that rustc isn't done until you can paste code from another language and following the suggestions you end up with valid Rust code without loss of the user's intent.
Part of the problem is that the places where incorrect code can fail is in more places than the parser. The chained comparisons example is one that is easy for Rust (as it doesn't support them), so the parser itself can produce a "missing turbofish" suggestion with high certainty, but for truly ambiguous expressions, the errors will happen later, during name resolution ("expected a value and found a type") or when checking the number of arguments. A production compiler needs to account for not only the original error, but also silence every knock-down error too. The simplest strategies are to just stop if at the end of a given stage there are errors (which leads to the "wave of errors" experience of fixing the "last" error leading to a ton of new ones) or fully replacing entire blocks of code that had a parse error with an AST node that acts as a tombstone marking that that later stages need to ignore it. The first option leads to a bad experience, and the latter is insufficient. A recent example of looking at this is https://github.com/rust-lang/rust/pull/159689, where `Arc::new(RwLock::new(HashMap<i32, i64>::default()));` currently produces
error[E0423]: expected value, found struct `HashMap`
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:11:34
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^^^^^^^
|
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
::: $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
= note: `HashMap` defined here
error[E0423]: expected value, found builtin type `i32`
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:11:42
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^^^ not a value
error[E0423]: expected value, found builtin type `i64`
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:11:47
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^^^ not a value
error[E0425]: cannot find external crate `default` in the crate root
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:11:53
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^^^^^^^ not found in the crate root
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:11:22
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^^^^^^^^^^^ --------------- unexpected argument #2 of type `bool`
|
note: associated function defined here
--> $SRC_DIR/std/src/sync/poison/rwlock.rs:LL:COL
help: remove the extra argument
|
LL - let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
LL + let _ = Arc::new(RwLock::new(HashMap<i32));
|
This is because the expression is syntactically correct as RwLock::new( HashMap < i32, i64 > ::default() );
^^^^^^^^^^^^ ------- - ---^ --- - ----------- ^
| | | | | | | |
| | | | | | | a function call to `default` in the crate root
| | | | | | a more than binop
| | | | | a value to be compared
| | | | the separator of the second argument to `RwLock::new()`
| | | a value to be compared
| | a less than binop
| a value to be compared
an associated function call
but after that PR it would only be the following, even though the parser hasn't changed: error: can't compare two types
--> $DIR/suggest-turbofish-parsed-as-comparisons.rs:24:41
|
LL | let _ = Arc::new(RwLock::new(HashMap<i32, i64>::default()));
| ^ ^ these are parsed as "less than" and "greater than"
|
help: you likely intended to write type `HashMap` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>`
|
LL | let _ = Arc::new(RwLock::new(HashMap::<i32, i64>::default()));
| ++
I think that there's a lot of work needed in the parser itself to produce good diagnostics. There are other strategies, like performing multiple parses at a given point when you've reached a known bad state (you've seen a flag-post that shouldn't be there, but that is a signal for a handful of other known cases), or fully consuming the rest of a block when an unrecoverable parse occurred (we're half-way through parsing function arguments, but failed? consume the rest of the statement or of the parent block, accounting for sub-scopes). The latter can cause the rest of the file to be consumed, but that's an edge-case that in practice is much better than a deluge of irrelevant errors.Another added complexity is how some easy-to-hit errors occur during lexing, which means the compiler has barely any information about the user's code. Mismatched braces/parens is one of those. rustc tries to provide context by keeping a queue of seen open delimiters to point at, and explicitly checking for their indentation level as a heuristic to detect where the user's intent diverged from the code, but that's overly reliant on the code being sanely formatted (thanks to rustfmt-on-save, that's a good bet for many users). For an example of the things rustc can do even in the lexer, you can look at https://github.com/rust-lang/rust/pull/160592.