Skip to content

Using an out-of-scope trait item on a boxed trait object should suggest use-ing the trait #105159

Closed
@shadowfacts

Description

@shadowfacts

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

added
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Dec 2, 2022
mcclure

mcclure commented on Dec 2, 2022

@mcclure

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

shadowfacts commented on Dec 2, 2022

@shadowfacts
Author

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):

candidates.retain(|candidate| *candidate != self.tcx.parent(result.callee.def_id));

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

compiler-errors commented on Dec 2, 2022

@compiler-errors
Member

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

compiler-errors commented on Dec 2, 2022

@compiler-errors
Member

Yeah, lol, I totally overlooked that the use would be load-bearing due to the way we treat trait methods on dyn Trait as inherent. I'll revert 88f2140, modify the test, etc.

added a commit that references this issue on Dec 3, 2022

Rollup merge of rust-lang#105164 - compiler-errors:revert-import-filt…

a739fc8
added a commit that references this issue on Jan 6, 2023

Rollup merge of rust-lang#105164 - compiler-errors:revert-import-filt…

8d33f31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @mcclure@compiler-errors@shadowfacts

    Issue actions

      Using an out-of-scope trait item on a boxed trait object should suggest use-ing the trait · Issue #105159 · rust-lang/rust