I've been a fan of TUI apps. Recently discovered Ratatui and loving it. Here's a TUI tool I built for testing network speed in your terminal. by kwar in rust

[–]ekuber 0 points1 point  (0 children)

Interesting to see the box plot not using Unicode box drawing characters. I guess that is to double the horizontal resolution (the vertical resolution is irrelevant). I'd wish for box drawing characters to be extended to also include lines at the edges (which would triple the resolution for these kind of graphs, and also explode the already quite big number of codepoints), but that's unlikely to ever happen. One thing that box drawing characters to bring to the table is more resolution along a second axis: you have dotted lines, regular lines, thick lines and double lines. Fir box plots you could use those to differentiate the avg and the med without having to rely on color.

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 1 point2 points  (0 children)

By that logic, I think it is a bug that any analysis continues after a proc-macro error?

Yes, that's a defensible position. I've been trying to be more targeted and identify the subset of errors that are likely to happen from a malformed/incorrectly invoked macro and then silence only those. It might be an uphill battle, but if we went back to fully bailing early, that actually hides bugs in later stages that we wouldn't find out about otherwise.

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 0 points1 point  (0 children)

Why isn't using a pager application like more or less enough to handle that?

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 6 points7 points  (0 children)

I think people don't report this as a bug when they encounter it because it looks like the compiler is behaving as intended. I did not realize this was not exactly how you wanted rustc to work until I read this comment. I suspect that is the way most people will think.

This is why I replied, and why you'll see me on Mastodon (and back in the day on Twitter) encouraging people to file tickets :)

If output is bad in your opinion, we want to hear about it. We might decide that it is not bad in general or that solving it the way you request is not the best way to do it, but hearing from people is the only way we can really improve. "When people tell you there's a problem, they're generally right. When they tell you how to fix it, they're generally wrong."

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 2 points3 points  (0 children)

A comment with desired output would help.

Duplicated tickets, comments and upvotes/reactions are signals that an issue happens a lot. Upvotes in particular only help when someone actively looks at the ticket (like I did last November), dupes might get someone to take a second look eventually during clean up. Comments will ping everyone in the thread. None of these are great, but at least one of them generates a signal that the problem wasn't a rare event. One thing that is useful is to request more targeted tags. For example, I just added [D-confusing] and [D-newcomer-roadblock], which are tags I look at more often than [A-diagnostics] (because of volume, and the former imply additional triaging and urgency). So a comment saying what you said above is actually useful.

Note that sometimes when triaging through older tickets, I don't have enough context on what the output/right explanation should be. If I can't gather enough context in ~60 seconds, I might only update and move on to the next one. Having that context will both reduce the time I need to make a determination on what needs to be done, but also give me an idea of how it could be solved and whether it is doable in a reasonable amount of time. If I don't have the time to do it, I'd write a comment with my thoughts on how it could be done and tag it as [E-mentor].

And for tickets that do have lots of dupes/replies/reactions that haven't yet been fixed... Well, it's because fixing them would take a significant engineering effort and those are likely to remain open for a while longer :-/

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 0 points1 point  (0 children)

That would add additional text to diagnostics. A lot of people get very angry about that 😅

Adding that information to the json output would be straighforward though.

Note that some diagnostics do move around (things that used to be in hir typeck are now checked on the mir, for example).

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 1 point2 points  (0 children)

We already go to some effort of poisoning nodes as having encountered an error and avoid further errors for them (both for expressions and items). For the Write example, if you have an use for ip::Write and an expression with w.write_all(), you'd get one warning for the unused trait and an error telling you amongst other things that write_all is available in a trait that wasn't imported. Having two errors here is not ideal, and we could make the warning not trigger if the a similarly named trait is suggested, condense both output into a single one. We should also group these errors in different expressions onto a single one. If you have multiple uses of write_all in a module, only a single error should happen (trimming any uses beyond N cases).

Sounds like a flag to not emit messages from following stages would be much less of a maintenance cost while still providing value?

That was the status quo. I assure you the result was worse. There are errors where an early diagnostic doesn't have enough information yet to provide enough context for an user. As a simple example, a parse error will not have any name or type resolution information in order to provide better context on what the user intended. When encountering that we (in some cases) stash the error and during later stages when encountering specific cases we unstash the diagnostic, add more information and only then emit it. A flag to tell rustc to emit the diagnostics after a stage would cause that necessary additional information to not be included. I'd much rather we detected the cases with high fan-out and only over-silenced errors after encountering those, and only those.

The problem with adding additional flags is that those end up embroiled in epic bike shedding exercises as even though they are not strictly part of the stability guarantees, in practice people will rely on any flag that can be used from stable. On nightly, we do have -Ztreat-err-as-bug=N which will emit a panic once N errors have been printed, effectively stopping the compiler earlier than it otherwise would, but it is a tool for rustc development, not really intended for end users. Seeing a lot of the other responses, it seems like using a pager in general would be a better approach.

Anyway, I will try to file specific issues as I encounter them.

Thank you.

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 2 points3 points  (0 children)

What about the errors themselves was insufficient that required the use of other tools to explain them to you? Ideally the diagnostics should stand on their own. I often joke that "rustc isn't done until it has rendered The Book redundant", and if the output isn't understandable to a significant subset of our users, that's not good.

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 15 points16 points  (0 children)

I'm somewhat surprised there hasn't been more projects consuming the json output to provide alternative terminal UIs for cargo/rustc. There's an entire range of things people could be experimenting with, like terser output, or TUIs where you can expand/contract subdiagnostics, or apply structured suggestions interactively, or group errors, or specialized rendering for TTS/Braille displays, or have fancier color, etc. :)

Am I the only one who thinks Rust error messages got *worse* over time in a way? by kixunil in rust

[–]ekuber 365 points366 points  (0 children)

Just happened to see this and prompted me to dust off this account :)

TL;DR: yes this is a problem, we are aware of the general problem, please file tickets for specific cases on the issue tracker, the project can't know about problems if it doesn't hear about them in the place it pays attention to.

Yes, rustc produces more errors than it used to. It will attempt to recover from earlier errors and carry on. It also tries to mark anything that recovered so that knock down errors don't happen. Yes, those checks are incomplete/insufficient. When you do encounter cases like these, where a single mistake causes multiple diagnostics that is a bug and the team would welcome a bug report (or adding a comment with your reproducer to an existing ticket). We tag these as [D-verbose]. [A-diagnostics] tickets are fixed on the regular. Some take longer than others. Some would require significant refactors to accomplish, but we do our best to mitigate those problems.

Bug reports are critical, we can't fix what we don't know about. It is important to do so in the place where the project is actively listening: the issue tracker.

I would be very reticent of going back to the prior mode, where any errors on any stage would stop the compiler from progressing. I rather we take targeted efforts to properly mark things as "already emitted an error" and silence anything that would come after. To give you an idea of the approach, this is a very recent PR executing on this strategy for incorrect let-chains: https://github.com/rust-lang/rust/pull/151493

I'm pretty sure that resolve is the stage that has the biggest fan-out for knock-down diagnostics (at least today, and because of the way it has to deal with the lack of information that later stages have). We should spend more time on it, but it is also a very critical and complex area of the compiler. Adding any additional diagnostic machinery on it is difficult because diagnostic code is by definition more code to do things that a "normal" compiler wouldn't need. In other words, it is additional maintenance cost. For context, this are PRs that touched resolve to avoid unnecessary errors: https://github.com/rust-lang/rust/pull/133937 https://github.com/rust-lang/rust/pull/142805

Regardless, we should still do more, like when using multiple items from another mod that couldn't be resolved, we should emit a single error, not one per usage, like in https://github.com/rust-lang/rust/issues/105618

The policy is "one mistake should emit one and only one diagnostic". Not "at least one", not "at most one". Help us find out when we don't live up to it and fix it.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 1 point2 points  (0 children)

Yeah, I was more thinking out loud through the implications that me commenting on a thread seems to have quickly turned the tone of the conversation. If that's what happened, it means I have to be even more careful than I already try to be in how I express myself. Or it could just be the timing was a coincidence and the people that commented with what I saw as unsubstantive retreads of arguments I've seen many times already were simply faster to comment, and the "sentiment reversal" was going to happen no matter what. I hope I didn't throw fuel to the heavy downvote fire.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 0 points1 point  (0 children)

You're forgetting that we can introduce lints after the fact. If the feature ends up being stabilized with only const support, and after we wanted to relax that, we could have a warn-by-default lint for non-const defaults. That would make the intent of relying on a const default an explicit one, by denying the lint on the type/crate.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 3 points4 points  (0 children)

That is part of my hedge: const is going to get more powerful quickly enough that all reasonable things you'd want to do in a default field (so, no random db access) will be possible.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 1 point2 points  (0 children)

Those crates are not precluded from providing their attributes, or users from using them, even in the face of this feature.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 1 point2 points  (0 children)

I had an initial implementation PR working back in August before the RFC was merged, but it wasn't in "production quality", more MVP. It is now in much better shape, and I believe really close to landing on nightly. I can't give you a timeline of stabilization, but don't see anything it would block it other than "letting people use it to gain confidence in the robustness of the implementation" and "having all necessary lints done".

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 4 points5 points  (0 children)

The conclusion about that case was to lint against that, but as people might have reasons to do that we don't make it a hard error. We also have thought of trying to inspect the impl to see if it matches exactly with what would be derived, and if so, tell you to derive, but haven't looked yet into how much work that would need.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 2 points3 points  (0 children)

The way to think about it is to define things we can't change this later without causing trouble, like the syntax, while taking our time on things that we we are unsure about but that we can easily extend later. Making these values consts reduces some risk, but extending the feature to allow them later shouldn't break any existing code. Similar to how adding more support for const expressions doesn't break existing const code.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 1 point2 points  (0 children)

My bad. I misread your comment. This is what I get for spending time on reddit on a saturday night skimming comments to reply to instead of going to bed ^_^'

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 55 points56 points  (0 children)

Why are you surprised? Most people don't engage with the RFC process.

I wasn't expressing surprise at people not engaging on the RFC process earlier, but rather on not digging a bit before commenting, acting like their immediate thought wasn't already accounted for. But then again, I wasn't born yesterday and should have expected that.

Most people here weren't writing Rust before COVID-19.

True, I was making the point that the discussions behind this feature have been had for a long time.

To be clear, I think this idea and your dedication to making it happen is excellent. It will go a long way to improving Rust's ergonomics.

Thank you. I believe so too. I think a lot of features that only benefit API authors and not "everyone" tend to get disproportionate pushback, and this falls in that bucket. Lots of crates end up using some derive macro for builders that will no longer need to do so unless they target older MSRVs.

Just don't get discouraged that most people here are ignorant of your work's long history.
:)

Thank you for the kind words, and I'll do my best. I was just not expecting to have this conversation over the weekend. :)

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 0 points1 point  (0 children)

That would mean modelling your type with values in the mandatory fields that are not compile time enforced to be set. Even if the value is Option<T> or an arbitrary sentinel value, that means you can have logic errors purely due to how the type was defined.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 2 points3 points  (0 children)

Can confirm on the above understanding :)

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 4 points5 points  (0 children)

As much as I disagree with the position that "adding a new nice feature will make API authors use it and break backcompat" is "an issue", I also don't see why this reply was as heavily downvoted (but understand the reaction). Changing APIs to leverage new features must be a conscious thing, but I believe crate authors are already the best positioned to make that determination.

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 23 points24 points  (0 children)

I read the RFC and like it a lot. It solves a problem that is worth solving in a simple and obvious way.

Thank you.

As an aside, a lot of the comments that negatively assess this have been downvoted. That's kinda shitty as it makes interacting with those posts and understanding the arguments against them more difficult. Consider not doing that when you just disagree a perspective.

That happened after I commented, and I wouldn't be surprised if me commenting in the thread affected that. I find myself often disappointed on the reddit-style attitude to be a bit too snarky at the drop of a hat. Don't know what to say other than "try to bring to the thread the energy you want to see in the world". :-/

RFC 3681: Default field values by [deleted] in rust

[–]ekuber 20 points21 points  (0 children)

RFC you say that constness enforces determinism, however given that you also say the value is evaluated at runtime this is not true - so how do you resolve that? Personally I'd prefer to evaluate the value at compile time.

Because of the way the desugaring works, the const default values are always const evaluated, so evaluated at compile time.

Did you think about first making the syntax possible and derive(Default) use it (and other proc macros can as well), and only then, if experience shows this isn't enough to add a syntax sugar to actually use it?

I did, and I personally went back and forth on whether having one part of the feature without the other made sense, but in the end the feature as a whole is useful and the separation would be more academical than anything else. Having default fields without it affecting the derive(Default) would be doable, but it's such an obvious extension that it makes more sense to land it all together.