Description
Summary
When you have nested type arguments, underlining an inner type argument and saying 'expected 1 type argument' does not obviously mean "expected [this to have] 1 type arg (but it hasn't got any)": it can also be read as "expected [this to be] 1 type arg (but it isn't one)".
Minimal complete example
Code that gives a confusing error message:
use std::sync::Arc;
use std::thread::JoinHandle;
struct Test {
// error on this line
handle1: Arc<JoinHandle>,
}
fn main() {
}
This results in the following error message:
error[E0107]: wrong number of type arguments: expected 1, found 0
--> error-wrong-number-of-type-args.rs:5:17
|
6 | handle1: Arc<JoinHandle>
| ^^^^^^^^^^ expected 1 type argument
Expected and observed interpretation by the user
Expected interpretation: rustc
wanted me to interpret underlining + "expected 1 type argument" as "This should have 1 type argument". In other words, this was the desired train of thought:
JoinHandle should have 1 type argument, rustc is pointing out to you which expression (JoinHandle plus its 0 or more type arguments) needs extra type arguments.
Observed interpretation: I interpreted underlining + "expected 1 type argument" + as "There should be 1 type argument here".** That led to the following train of thought:
Arc
should have 1 type argument, and rustc is pointing out to me where the type argument should go. So JoinHandle is not a type argument? But why?! 😕 I thought JoinHandle was a type argument... [I then spent 30 minutes going through lessons and docs on type arguments, Arc, and JoinHandle, looking for clues. I only realised the answer when I opened the provided solution code to compare.]
Some notes on the user persona: the user (me, in this case) was somebody with about 10 years experience programming R and Python; they had read The Rust Programming Language; they were working on lesson 7 of Michael Snoyman's Rust Crash Course when they encountered this error message; they lurked sometimes on the /r/rust subreddit; and they had no experience of Rust beyond that.
Not as problematic when user has passed at least 1 type arg
This particular form of the E0107 error message is printed whenever provided type args < required type args
. But it's less ambiguous when the user has passed at least one type arg, because then the entire expression (the type and its too-few args) gets underlined:
--> error-wrong-number-of-type-args.rs:7:18
|
6 | handle2: Arc<Result<i32>>
| ^^^^^^^^^^^ expected 2 type arguments
Possible fixes
Potential fix 1: change error phrasing to "expected this to have 1 type argument"
This fix is (a) an improvement on the current message, and (b) easy to implement -- a one-line change in the code. The message takes a (little!) bit more work to parse, when you break it down: knowing what 'this' refers to relies on reading the underlining and mentally discarding the type args.
|
6 | handle1: Arc<JoinHandle>
| ^^^^^^^^^^ expected this to have 1 type argument
|
6 | handle2: Arc<Result<i32>>
| ^^^^^^^^^^^ expected this to have 2 type arguments
Potential fix 2: mention the type's name in the error message
I like this fix a lot better, because it makes the error message self-contained and unambiguous while keeping it short. But getting the type name into the string requires more intimate knowledge of the error-reporting code, so you need a bit more codebase knowledge to fix it.
|
6 | handle1: Arc<JoinHandle>
| ^^^^^^^^^^ expected JoinHandle to have 1 type argument
|
6 | handle2: Arc<Result<i32>>
| ^^^^^^^^^^^ expected Result to have 2 type arguments
Who could do the work
The relevant code is in astconv.rs#L389-L397
If we choose fix 1, I could create a pull request for that -- it's a one-line fix.
For fix 2, I'd be willing to help out, but at the moment I'm not sure how to obtain the span of code that refers to only to the type that didn't get enough parameters. For something this unimportantant, the maintainer might get a better return on investment if they did it themselves, or opted for fix 1.
Meta
rustc --version --verbose
:
rustc 1.40.0-nightly (1423bec54 2019-11-05)
binary: rustc
commit-hash: 1423bec54cf2db283b614e527cfd602b481485d1
commit-date: 2019-11-05
host: x86_64-unknown-linux-gnu
release: 1.40.0-nightly
LLVM version: 9.0
This issue has been assigned to @Patryk27 via this comment.