Skip to content
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

Associated function from super traits not accessible via sub traits #124438

Open
WaffleLapkin opened this issue Apr 27, 2024 · 2 comments
Open

Associated function from super traits not accessible via sub traits #124438

WaffleLapkin opened this issue Apr 27, 2024 · 2 comments
Labels
A-associated-items Area: Associated items such as associated types and consts. A-diagnostics Area: Messages for errors, warnings, and lints A-resolve Area: Path resolution A-trait-objects Area: trait objects, vtable layout C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@WaffleLapkin
Copy link
Member

I tried this code:

trait Super {
    fn assoc() -> Self;
}

trait Sub: Super {}

fn f<T: Sub>() -> T {
    // doesn't work
    Sub::assoc()
    // works
    // Super::assoc()
}

(play)

I expected to see this happen: the code compiles with either Sub::assoc() or Super::assoc().

Instead, this happened: five compilation errors which is very confusing:

error[E0782]: trait objects must include the `dyn` keyword
 --> src/lib.rs:9:5
  |
9 |     Sub::assoc()
  |     ^^^
  |
help: add `dyn` keyword before this trait
  |
9 |     <dyn Sub>::assoc()
  |     ++++    +

error[E0038]: the trait `Sub` cannot be made into an object
 --> src/lib.rs:9:5
  |
9 |     Sub::assoc()
  |     ^^^ `Sub` cannot be made into an object
  |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 --> src/lib.rs:2:8
  |
2 |     fn assoc() -> Self;
  |        ^^^^^ ...because associated function `assoc` has no `self` parameter
...
5 | trait Sub: Super {}
  |       --- this trait cannot be made into an object...
help: consider turning `assoc` into a method by giving it a `&self` argument
  |
2 |     fn assoc(&self) -> Self;
  |              +++++
help: alternatively, consider constraining `assoc` so it does not apply to trait objects
  |
2 |     fn assoc() -> Self where Self: Sized;
  |                        +++++++++++++++++

error[E0308]: mismatched types
 --> src/lib.rs:9:5
  |
7 | fn f<T: Sub>() -> T {
  |      -            -
  |      |            |
  |      |            expected `T` because of return type
  |      |            help: consider using an impl return type: `impl Sub`
  |      expected this type parameter
8 |     // doesn't work
9 |     Sub::assoc()
  |     ^^^^^^^^^^^^ expected type parameter `T`, found `dyn Sub`
  |
  = note: expected type parameter `T`
               found trait object `dyn Sub`
  = help: type parameters must be constrained to match other types
  = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

error[E0038]: the trait `Sub` cannot be made into an object
 --> src/lib.rs:9:5
  |
9 |     Sub::assoc()
  |     ^^^^^^^^^^^^ `Sub` cannot be made into an object
  |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
 --> src/lib.rs:2:8
  |
2 |     fn assoc() -> Self;
  |        ^^^^^ ...because associated function `assoc` has no `self` parameter
...
5 | trait Sub: Super {}
  |       --- this trait cannot be made into an object...
help: consider turning `assoc` into a method by giving it a `&self` argument
  |
2 |     fn assoc(&self) -> Self;
  |              +++++
help: alternatively, consider constraining `assoc` so it does not apply to trait objects
  |
2 |     fn assoc() -> Self where Self: Sized;
  |                        +++++++++++++++++

error[E0277]: the size for values of type `dyn Sub` cannot be known at compilation time
 --> src/lib.rs:9:5
  |
9 |     Sub::assoc()
  |     ^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `dyn Sub`
  = note: the return type of a function must have a statically known size

Meta

rustc version: 1.77.2.

@WaffleLapkin WaffleLapkin added A-resolve Area: Path resolution A-associated-items Area: Associated items such as associated types and consts. C-bug Category: This is a bug. A-trait-objects Area: trait objects, vtable layout labels Apr 27, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 27, 2024
@EsotericPyramid
Copy link

I don’t believe this actually a bug at all.

  1. That’s not how you call associated functions. The syntax for that is Type::func() not Trait::func(). That’s why the compiler gives notes about making a dynamic trait object because that would give you an actual type for the correct syntax. If you could call associated functions with the Trait::func syntax then it may be impossible for the compiler to pick an implementation as multiple implementations for different types could have identical signatures (not in this particular case)
  2. assoc is not part of the Sub trait, it is required by it so <T as Sub>::assoc() wouldn’t work but <T as Super>::assoc() should. This is important as it allows both Sub and Super to have an associated function with the same name.

@workingjubilee
Copy link
Contributor

confusing diagnostics are still bugs.

@saethlin saethlin added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-diagnostics Area: Messages for errors, warnings, and lints and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels May 11, 2024
@WaffleLapkin WaffleLapkin added D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. labels May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-diagnostics Area: Messages for errors, warnings, and lints A-resolve Area: Path resolution A-trait-objects Area: trait objects, vtable layout C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants