rust-lang / rust-lang/rust

`Trait::nonexistant` treats `Trait` as a type, resulting in bad errors

Open
#136,994 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics D-confusing D-newcomer-roadblock T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

cc https://github.com/rust-lang/rust/issues/58734

trait Trait {
    fn exists(self) -> ();
    fn not_object_safe() -> Self;
}

impl Trait for () {
    fn exists(self) -> () {}
    fn not_object_safe() -> Self {}
}

fn main() {
    // This call is fully resolved during name resolution, its
    // self type is an inference variable.
    Trait::exists(());
    // We fail to resolve `nonexistent` during nameres, so this
    // call gets lowered to a type dependent path instead, attempting
    // to lower `Trait` as a type in the process.
    Trait::nonexistent(());
}

Lowering Trait results in the following error in edition 2021

error[E0782]: expected a type, found a trait
  --> src/main.rs:18:5
   |
18 |     Trait::nonexistent(());
   |     ^^^^^
   |
help: you can add the `dyn` keyword if you want a trait object
   |
18 |     <dyn Trait>::nonexistent(());
   |     ++++      +

and the following in previous editions

error[E0038]: the trait `Trait` is not dyn compatible
  --> $DIR/issue-58734.rs:20:5
   |
LL |     Trait::nonexistent(());
   |     ^^^^^ `Trait` is not dyn compatible
   |
note: for a trait to be dyn compatible it needs to allow building a vtable
      for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
  --> $DIR/issue-58734.rs:4:8
   |
LL | trait Trait {
   |       ----- this trait is not dyn compatible...
...
LL |     fn dyn_incompatible() -> Self;
   |        ^^^^^^^^^^^^^^^^ ...because associated function `dyn_incompatible` has no `self` parameter
   = help: only type `()` implements `Trait`; consider using it directly instead.
help: consider turning `dyn_incompatible` into a method by giving it a `&self` argument
   |
LL |     fn dyn_incompatible(&self) -> Self;
   |                         +++++
help: alternatively, consider constraining `dyn_incompatible` so it does not apply to trait objects
   |
LL |     fn dyn_incompatible() -> Self where Self: Sized;
   |                                   +++++++++++++++++

error[E0599]: no function or associated item named `nonexistent` found for trait object `dyn Trait` in the current scope
  --> $DIR/issue-58734.rs:20:12
   |
LL |     Trait::nonexistent(());
   |            ^^^^^^^^^^^ function or associated item not found in `dyn Trait`

Both errors are quite bad and should be fixed by a more principled approach.

#136928 removed a hack which avoided emitting a WF obligation for the self type if method resolution failed, avoiding the "the trait Trait is not dyn compatible" error in edition 2018.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided reproducer in src/main.rs and compare its diagnostics across editions, including the $DIR/issue-58734.rs case. Read issue #136928 for the related name-resolution and well-formedness behavior. Done means the unresolved associated-item call no longer produces misleading trait-object or type errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.