Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lcnr opened this issue Feb 13, 2025 · 0 comments
Open

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

lcnr opened this issue Feb 13, 2025 · 0 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@lcnr
Copy link
Contributor

lcnr commented Feb 13, 2025

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.

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 13, 2025
@lcnr lcnr changed the title Trait::nonexistant error handling is quite poor Trait::nonexistant treats Trait as a type, resulting in bad errors Feb 13, 2025
@jieyouxu jieyouxu added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants