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

Component props (fn params) should not be named prop #3543

Open
flba-eb opened this issue Jan 11, 2025 · 2 comments
Open

Component props (fn params) should not be named prop #3543

flba-eb opened this issue Jan 11, 2025 · 2 comments
Labels
documentation Improvements or additions to documentation

Comments

@flba-eb
Copy link
Contributor

flba-eb commented Jan 11, 2025

Problem

The Dioxus 0.6 component props doc suggests that it is okay to name a prop prop, e.g.

fn Likes(props: LikesProps) -> Element {...}

However, this (sometimes?) fails to compile. See below for the error message.

Steps To Reproduce

Simplified shorthand example.

Text search and replace (over complete file) from props to a_props does fix the problem.

//! Dioxus supports shorthand syntax for creating elements and components.

use dioxus::prelude::*;

fn main() {
    dioxus::launch(app);
}

fn app() -> Element {
    let props = 123;
    let class = "class";
    let id = "id";

    // todo: i'd like it for children on elements to be inferred as the children of the element
    // also should shorthands understand references/dereferences?
    // ie **a, *a, &a, &mut a, etc
    let children = rsx! { "Child" };

    rsx! {
        div { class, id, {&children} }
        Component { props }
    }
}

#[component]
fn Component(props: i32) -> Element {
    rsx! {
        div { "{props}" }
    }
}

Resulting error message:

error[E0277]: `Props` is not implemented for `i32`
   --> web/src/shorthand.rs:19:5
    |
19  | /     rsx! {
20  | |         div { class, id, {&children} }
21  | |         Component { props }
22  | |     }
    | |_____^ Props
    |
    = help: the trait `dioxus::prelude::Properties` is not implemented for `i32`
    = note: Props is a trait that is automatically implemented for all structs that can be used as props for a component
    = note: If you manually created a new properties struct, you may have forgotten to add `#[derive(Props, PartialEq, Clone)]` to your struct
    = help: the following other types implement trait `dioxus::prelude::Properties`:
              ()
              dioxus::dioxus_core::error_boundary::ErrorBoundaryProps
              dioxus::dioxus_core::fragment::FragmentProps
              dioxus::dioxus_core::suspense::component::SuspenseBoundaryPropsWithOwner
              dioxus::dioxus_document::LinkProps
              dioxus::dioxus_document::MetaProps
              dioxus::dioxus_document::ScriptProps
              dioxus::dioxus_document::StyleProps
            and 14 others
note: required by a bound in `dioxus::prelude::fc_to_builder`
   --> /home/flo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/dioxus-core-0.6.1/src/properties.rs:112:8
    |
110 | pub fn fc_to_builder<P, M>(_: impl ComponentFunction<P, M>) -> <P as Properties>::Builder
    |        ------------- required by a bound in this function
111 | where
112 |     P: Properties,
    |        ^^^^^^^^^^ required by this bound in `fc_to_builder`
    = note: this error originates in the macro `rsx` (in Nightly builds, run with -Z macro-backtrace for more info)

Expected behavior

One of:

  • Documentation clearly says this is not allowed and examples don't use it, and the #[component] macro detects this issue and reports it.
  • It just compiles.

Environment:

  • Dioxus version: v0.6.1
  • Rust version: 1.83.0
  • OS info: WSL, Ubuntu 22.04
  • App platform: web
@aynaash
Copy link

aynaash commented Jan 11, 2025

I would love to work on this. Can I ?

@ealmloff ealmloff added bug Something isn't working documentation Improvements or additions to documentation and removed bug Something isn't working labels Jan 13, 2025
@ealmloff
Copy link
Member

This was implemented in #2105. If the keyword props is used, then it is passed through as the props instead of added as a field. I don't think this is documented anywhere in the component macro or docsite. We should add documentation about the feature to both.

In addition to documentation we could improve the error message by generating an auto trait in the component macro with a nicer diagnostic message. Something like this assertion:

// the component macro could expand to code with this assertion for nicer error messages when the props field is included without implementing the properties trait
const _: () = {
   #[diagnostic::on_unimplemented(message = "The type passed with the props name in the component macro must implement Properties", label = "Properties for Component", note = "The props field in the component macro makes the component macro use that field as the props for the component instead of a field in a generated props struct. Because it is used as the props, it must implement Properties")]  
   trait PropsFieldRequiresProps: Properties {}
   impl<P: Properties> PropsFieldRequiresProps for P {}
   const fn require_props<P: PropsFieldRequiresProps>() {}
   // Insert the type from the props field here where i32 is
   require_props::<i32>()
};

That will generate an error message like this:

error[E0277]: The type passed with the props name in the component macro must implement Properties
  --> src/main.rs:42:17
   |
42 |    fn Component(props: i32) -> Element {
   |                        ^^^ Properties for Component
   |
   = help: the trait `dioxus::prelude::Properties` is not implemented for `i32`
   = note: The props field in the component macro makes the component macro use that field as the props for the component instead of a field in a generated props struct. Because it is used as the props, it must implement Properties
   = help: the following other types implement trait `dioxus::prelude::Properties`:
             ()
             LinkProps
             MetaProps
             ScriptProps
             StyleProps
             SuspenseBoundaryProps
             TitleProps
             dioxus::dioxus_core::error_boundary::ErrorBoundaryProps
           and 2 others
note: required for `i32` to implement `PropsFieldRequiresProps`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants