Skip to content

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

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.

Activity

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

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