Pre-RFC?: rustc UX Guidelines


#1

The Rust language has a style guide and it’s followed pretty well. That’s great, but what about the other stylistic aspects of the rustc compiler? Things like how error messages are supposed to be written and other similar things. There’s currently no user experience guidelines document. I sent in a PR for one given some error message stuff, but we probably need an RFC to actually come to an agreement about what our user experience is with the compiler.

Areas of user experience that I can think of include error messages, compiler flags, the help file, what is emitted during success, and basically any user facing interface interactions.

Here’s what I came up with for a start, but it’s woefully incomplete. For areas where you’ve worked on UX, are there any decisions you made that should be codified into a guidelines document? Do we actually need an RFC for this? Are we going to also want to have guidelines for other projects (cargo, racer, etc.)?


#2

And for an actual RFC…


  • Feature Name: ux-guidelines
  • Start Date: 2015-07-30
  • RFC PR: (leave this empty)
  • Rust Issue: (leave this empty)

Summary

This is a conventions RFC to settle and document a number of UX guidelines.

  • Error Messages
  • Explain Messages
  • Compiler flags

Motivation

Good user experience is paramount for happy users. We already have informal guidelines, and having them documented makes it easier for new developers to start contributing without regressing on user experience.

Detailed design

This RFC includes a number of unrelated UX guidelines broken down into arbitrary subsections. It starts with an overall summary of the goals of these guidelines. Ideally, everything after this paragraph should be copyable into a ux-guidelines.md file into the rustc repo.

Summary

Don’t forget the user. Whether human or another program, such as an IDE, a good user experience with the compiler goes a long way into making developer lives better. And when developer lives are better, they can make their users’ lives better as well. We don’t want users to be baffled by compiler output or learn arcane patterns to compile their program.

Error, Warning, Help, Note Messages

When the compiler detects a problem, it can emit either an error, warning, note, or help message.

An error is emitted when the compiler detects a problem that makes it unable to compile the program, either because the program is invalid or the programmer has decided to make a specific warning into an error.

A warning is emitted when the compiler detects something odd about a program. For instance, dead code and unused Result values.

A help is emitted following either an error or warning giving extra information to the user about how to solve their problem.

A note is for identifying additional circumstances and parts of the code that lead to a warning or error. For example, the borrow checker will note any previous conflicting borrows.

  • Write in plain simple English. If your message, when shown on a – possibly small – screen (which hasn’t been cleaned for a while), cannot be understood by a normal programmer, who just came out of bed after a night partying, it’s too complex.
  • Errors and Warnings should not suggest how to fix the problem. A Help message should be emitted instead.
  • Error, Warning, Note, and Help messages start with a lowercase letter and do not end with punctuation.
  • Error messages should be succinct. Users will see these error messages many times, and more verbose descriptions can be viewed with the --explain flag. That said, don’t make it so terse that it’s hard to understand.
  • The word “illegal” is illegal. Prefer “invalid” or a more specific word instead.
  • Errors should document the span of code where they occur – the span_.. methods allow to easily do this. Also note other spans that have contributed to the error, if any (and only if the span isn’t too large – is there a limit btw.?)
  • When emitting a message with span, try to reduce the span to the smallest amount possible that still signifies the issue
  • Try not to emit multiple error messages for the same error. This may require detecting duplicates.
  • When the compiler has too little information for a specific error message, lobby for annotations for library code that allow adding more. (e.g. see #[on_unimplemented]). Use these annotations when available!
  • Keep in mind that Rust’s learning curve is rather steep, and that the compiler messages are an important learning tool.

Error Explanations

Error explanations are long form descriptions of error messages provided with the compiler. They are accessible via the --explain flag. Each explanation comes with an example of how to trigger it and advice on how to fix it.

Compiler Flags

  • Always give options a long descriptive name, if only for better understandable compiler scripts.
  • The --verbose flag is for adding verbose information to rustc output when not compiling a program. For example, using it with the --version flag gives information about the hashes of the code.
  • Experimental flags must be behind the -Z flag.

Drawbacks

None.

Alternatives

Have no UX guidelines.

Unresolved questions

What other UX guidelines exist but aren’t documented anywhere?

What happens when a warning or error subsumes another warning or error?

How should the UX guidelines be added to in the future? Not every addition will be forcing a new style, but rather, just documenting practice already done. Should they just be added via a Pull Request?


#3

I have a few other points that should perhaps be documented.

  • Errors should document the span of code where they occur – the span_… methods allow to easily do this. Also note other spans that have contributed to the error, if any (and only if the span isn’t too large – is there a limit btw.?)
  • When emitting a message with span, try to reduce the span to the smallest amount possible that still signifies the issue
  • Try not to emit multiple error messages for the same error (this may require detecting duplicates)
  • When the compiler has too little information for a specific error message, lobby for annotations for library code that allow adding more (e.g. see #[on_unimplemented] – can we stabilize this?). Also use it when available!
  • Write in plain simple English. If your sentence, when shown on a – possibly small – screen (which hasn’t been cleaned for a while), cannot be understood by a normal programmer, who just came out of bed after a night partying, it’s probably, or some would say obviously, too complex
  • Keep in mind that Rust’s learning curve is rather steep, and that the compiler messages are an important learning tool

By the way, is there a way to report e.g. a warning + help message that both reference a span without repeating the code in the output?


#4

That’s a lot of good points. Thanks! I’ve added them wholesale for now, since I need to go to bed. (This includes the questions…) Will edit when I wake up.


#5

Or better. After writing each error drink enough booze to get tipsy. Can you still understand the message you wrote?

If yes, then proceed to partying. If not, grab a snack, sober up and rewrite the whole thing, until you can understand it while drunk :slight_smile:

Useful resource:


#6

Sorry, Daniel, but I strongly oppose this, for fear of rampant alcoholism in our community.

Therefore I propose a better procedure:

  1. Try to obtain borrow a six year old (I only have a five-year old daughter. She has yet to program a single line of code, but at least she assembled her own RasPI, so there’s that)
  2. Read the error message to the aforementioned six year old (I do have to translate to German, as her English is a bit sub-par as of yet. I’m not sure if that augmentation of the procedure makes it better or worse)
  3. Discuss the error message, what it means and make note of anything a) you have to explain or b) that is misunderstood

This method should work even better with a six-year-old who actually codes, but let’s make do with what we have.

Bonus points for teaching Rust to six-year-olds.


#7

This unnecessarily discriminates against teetotalers and people who don’t drink.

runs screaming from this thread


#8

@DanielKeep: You are correct. I haven’t took into consideration that some religions prohibit drinking. For shame :frowning:

I think ilogiq meant as in building a child from scratch. I’ve heard there are human factories walking around. You could ask one of them to Clone you. Well, PartialClone :wink:


#9

@DanielKeep / @DanielFath:

Forgive me if this sounds somewhat macabre, but you do not need to mutably own the child.

Perhaps you can borrow one?


#10

No, officer, you don’t understand. A man on the internet told me to obtain a six year old, and I figured the daycare was… yes, a man. Well, OK, they might not be a man. You know what the internet is like.

Could be a dog for all I know…

What? No! I needed it to read documentation. For a library. Look, it’s quite straightforward: I get the six year old, make them read technical documentation and see if they understood it.

Well I don’t know; the instructions didn’t cover what to do after that.

Of course that was in my search history; where else am I supposed to get a small child at short notice?

No, they don’t seem overly fond of me. Also, I have crippling social anxiety.

Say, can I go now, I need to make a small white square into a green square or recruiters will think I’m not a rockstar programmer. Hey, are you coming back? Hello?

Can I at least get the Wi-Fi password?


#11

Moral of the story: Don’t trust people (or dogs or other entities) on the internet.


#12

On a more serious note:

How would implement stuff like Elm’s advanced help in Rust? Would they even make sense? --explain only works to explain what some type of error is, it doesn’t go into detail of your current impl.


#13

In fact, it cannot go into details of your current code, because it doesn’t know which code to refer to. This is a problem in current Rust, because we should be able to give more direct information (e.g. using --verbose).


#14

Agreed, a set of guidelines covering ‘what makes a good warning/error’ is really worthwhile. This seems like a useful checklist for good practices.

However, this surprised me: I love useful suggestions when I’ve made a mistake.

As a beginner rust programmer, when rustc says ‘did you mean…’ or ‘consider adding…’ it’s usually right. What don’t you like about suggestions?


#15

That should be a help, which is an additional message to the warning/error.


#16

I’d especially like to get some guidelines on compiler flags. Anybody who’s worked on compiler flags have some wisdom on how to properly design them? Possibly even advice on when to and when not to add new flags?


#17

I also feel that the distinction between note and help hasn’t been clear in the implementations. Sometimes I see notes that I would think would be help messages. Having documentation on this as well would be helpful.


#18

Agreed, a bit more documentation would go a long way. Then again, I’ve written a lot of code without reading much of the docs we have, so I’m partially to blame for the instances in clippy where we note where we could have helped.

Havvy: I think I can add two important points regarding command line flags:

  • Don’t forget the user: This includes humans (which as we know are prone to errors, but able to do great things), as well as other programs (e.g. any IDE that wishes to somehow display our compiler output).
  • Always give a long, descriptive option name, too (if only for better understandable compile scripts).

#19

The first one makes a good summary for UX in general. I added a summary section with that.

The second one I added to the document. So now there’s a singular UX guideline for command line flags.


#20

One thing I’d like to see is verbose messages – we do have the --verbose command line argument, but I don’t see any code using it.