Skip to content

Be more pedagogic on why assoc fns without receiver aren't dyn-safe #159492

Description

@estebank

Code

trait Factory {
    fn create() -> Box<dyn Factory>;
    //~^ ERROR the trait `Factory` is not dyn compatible
}

fn use_factory(_: &dyn Factory) {}

// The diagnostic explains the mechanical rule, but not that a receiver-less constructor cannot be
// selected from a trait object or that `where Self: Sized` makes this intent explicit.
fn main() {}

Current output

error[E0038]: the trait `Factory` is not dyn compatible
  --> $DIR/static-constructor-prevents-dyn-no-api-guidance.rs:12:20
   |
LL | fn use_factory(_: &dyn Factory) {}
   |                    ^^^^^^^^^^^ `Factory` 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/static-constructor-prevents-dyn-no-api-guidance.rs:8:8
   |
LL | trait Factory {
   |       ------- this trait is not dyn compatible...
LL |     fn create() -> Box<dyn Factory>;
   |        ^^^^^^ ...because associated function `create` has no `self` parameter
help: consider turning `create` into a method by giving it a `&self` argument
   |
LL |     fn create(&self) -> Box<dyn Factory>;
   |               +++++
help: alternatively, consider constraining `create` so it does not apply to trait objects
   |
LL |     fn create() -> Box<dyn Factory> where Self: Sized;
   |                                     +++++++++++++++++

Desired output

error[E0038]: the trait `Factory` is not dyn compatible
  --> $DIR/static-constructor-prevents-dyn-no-api-guidance.rs:12:20
   |
LL | fn use_factory(_: &dyn Factory) {}
   |                    ^^^^^^^^^^^ `Factory` 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/static-constructor-prevents-dyn-no-api-guidance.rs:8:8
   |
LL | trait Factory {
   |       ------- this trait is not dyn compatible...
LL |     fn create() -> Box<dyn Factory>;
   |        ^^^^^^ ...because associated function `create` has no `self` parameter
help: consider turning `create` into a method by giving it a `&self` argument, so that it is accessible through the trait object's vtable
   |
LL |     fn create(&self) -> Box<dyn Factory>;
   |               +++++
help: alternatively, consider constraining `create` so it is explicitly marked as not applying to trait objects
   |
LL |     fn create() -> Box<dyn Factory> where Self: Sized;
   |                                     +++++++++++++++++

Rationale and extra context

The wording can be iterated on, let's just try to add more context.

Other cases

Rust Version

1.97

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-lowLow priorityT-compilerRelevant to the compiler 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