Closed
Description
Given the following code:
use std::io::{stdin, BufReader};
fn main() {
let reader: Box<dyn std::io::BufRead> = Box::new(BufReader::new(stdin()));
let _ = reader.lines();
}
The current output is:
error: the `lines` method cannot be invoked on a trait object
--> src/main.rs:5:20
|
5 | let _ = reader.lines();
| ^^^^^
|
::: /Users/shadowfacts/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/io/mod.rs:2276:15
|
2276 | Self: Sized,
| ----- this has a `Sized` requirement
Ideally the output should suggest use
-ing the out-of-scope trait, similar to E0599:
error[E0599]: no method named `lines` found for struct `BufReader` in the current scope
--> src/main.rs:6:20
|
6 | let _ = reader.lines();
| ^^^^^ method not found in `BufReader<Stdin>`
|
::: /Users/shadowfacts/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/io/mod.rs:2274:8
|
2274 | fn lines(self) -> Lines<Self>
| ----- the method is available for `BufReader<Stdin>` here
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
1 | use std::io::BufRead;
|
Someone tried to do dynamic dispatch between two underlying BufReaders
used a boxed trait object (with the type spelled Box<dyn io::BufRead>
, so BufRead
wasn't in scope) and call the lines
method on the boxed reader, and it was unclear from the error why the method wasn't accessible:
https://mastodon.social/@mcc/109441482880682856
This is reproducible on nightly (rustc 1.67.0-nightly (c090c68 2022-12-01)).
Activity
mcclure commentedon Dec 2, 2022
Note: A sign there may be a problem worth fixing here is the code I wrote is a near copypaste of a top stack overflow answer for a common problem :)
shadowfacts commentedon Dec 2, 2022
So, after some investigating, this appears to be a regression of #35976, which added essentially the same suggestion I proposed here: adding a
use
for the trait object's trait.When generating the error when the lookup fails, the trait is initially included in the list of candidates, but it's filtered out by this
retain
(because the callee is the trait method, and so the parent of the callee is the trait, which is the candidate):rust/compiler/rustc_hir_typeck/src/method/mod.rs
Line 239 in 56c241c
This was introduced in 88f2140 by @compiler-errors, which also removed the corresponding suggestion from the #35976 test's expected output. It's not immediately clear to me from the PR (#99146) why this change was necessary. If the
retain
call is removed, the only UI test that fails is the #35976 one. Reverting that change would fix this issue, but I'm not sure if there are other cases I'm missing.(cc @estebank, with whom I was discussing this on Mastodon)
compiler-errors commentedon Dec 2, 2022
Haven't look at this yet, maybe I misinterpreted what 88f4120 was achieving, and that commit just needs a revert 🤷 -- can't recall why I did that.
compiler-errors commentedon Dec 2, 2022
Yeah, lol, I totally overlooked that the
use
would be load-bearing due to the way we treat trait methods ondyn Trait
as inherent. I'll revert88f2140
, modify the test, etc.use
suggestion fordyn
method call requiringSized
#105164Rollup merge of rust-lang#105164 - compiler-errors:revert-import-filt…
Rollup merge of rust-lang#105164 - compiler-errors:revert-import-filt…