Skip to content

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

Open
@lcnr

Description

@lcnr

cc #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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions