Description
Currently (for three months, since #12422), stdin()
returns a buffered reader.
This is causing lots of trouble with people that write
let a = io::stdin().read_line();
let b = io::stdin().read_line();
The first read will typically consume all the data from stdin, and so b
ends up None
, the rest of the first stdin()
call having mysteriously vanished.
Documentation that you should only call stdin()
once is not sufficient. It needs to be either a compile error in some way (once fn stdin()
!?) or calling stdin()
multiple times must be safe. (Causing task failure, “you’ve already called stdin()!”, would probably not be considered acceptable.)
One suggestion is to switch it to using task-local storage. This is imperfect (reading stdin from multiple tasks is broken), but generally acceptable.
Having stdin/stdout/stderr as true globals in some way is another possibility.
Yet another suggestion, aired by @o11c, is passing stdin, stdout and stderr as arguments to main
. (There are certainly significant difficulties with that scheme.)
This needs to be fixed urgently. It appears to be tripping up a significant number of people and is very much non-obvious.