Unknown size at compilation time on function call

Hi,

I've a unknown size at compilation time on function call.
And I don't really understand why.
Is it cause by the trait with types inside ?
Is it possible to easily fix it ?

Here's the error :

error[E0277]: the size for values of type `(dyn entities::component::Component + 'static)` cannot be known at compilation time
  --> src\business\component\get_all_for_page.rs:48:22
   |
48 |         Some(b) => b.build_component(data.content, None),
   |                      ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `(dyn entities::component::Component + 'static)`

And here's the code :

pub type DynComponentBuilder = dyn ComponentBuilder<AdminComponent=dyn Component,BaseComponent=dyn Component>;

pub trait ComponentBuilder: Send + Sync {
    type BaseComponent: Component;
    type AdminComponent: Component;

    fn build_component(&self, _content: serde_json::Value, _lang: Option<String>) -> Result<Self::BaseComponent, MhcError> {
        Ok(self.build_demo())
    }

    fn build_demo(&self) -> Self::BaseComponent;

    fn build_form(&self) -> Self::AdminComponent;
}

pub struct GetBuilderUseCase;

impl UseCaseBoundary for GetBuilderUseCase {
    type InputMessage = String;
    type OutputMessage = MhcResult<Option<Arc<DynComponentBuilder>>>;

    fn execute(&self, message: &Self::InputMessage) -> Self::OutputMessage {
        match REGISTERED_COMPONENT_BUILDERS.lock() {
            Ok(builders) => Ok(builders.get(message.as_str()).cloned()),
            Err(error) => Err(MhcError::from(error)),
        }
    }
}

fn build_component_from_data(data: ComponentData) -> MhcResult<Box<dyn Component>> {
    match GetBuilderUseCase.execute(&data.type_id)? {
        Some(b) => b.build_component(data.content, None),
        None => Err(MhcError::from(ErrorType::NotFound)),
    }
}

Thank you :slight_smile:

dyn Trait is dynamically sized and also requires a vtable to be usable, so when it comes to dyn Trait values, they will be behind some kind of pointer -- &dyn Trait, Box<dyn Trait>, Arc<dyn Trait>, etc.

pub type DynComponentBuilder = dyn ComponentBuilder<
    AdminComponent=dyn Component,
    BaseComponent=dyn Component,
>;

pub trait ComponentBuilder: Send + Sync {
    type BaseComponent: Component;
    type AdminComponent: Component;

    fn build_demo(&self) -> Self::BaseComponent;
    fn build_form(&self) -> Self::AdminComponent;
}

You can't return unsized values like dyn Trait, so dyn Trait doesn't make sense as the BaseComponent or AdminComponent types. Also, associated types (and generic type parameters) have an implicit Sized bound (which can be removed with : ?Sized).

So either these signatures (and any other that imply the associated types must be Sized) has to change and ?Sized has to be added to the associated types...

pub trait ComponentBuilder: Send + Sync {
    type BaseComponent: Component + ?Sized;
    type AdminComponent: Component + ?Sized;

    fn build_demo(&self) -> Box<Self::BaseComponent>;
    fn build_form(&self) -> Box<Self::AdminComponent>;
}

...or your type alias needs to be changed to use Sized types, and you need to make sure that the trait is implemented for those types (or change the bounds on the associated types).

pub type DynComponentBuilder = dyn ComponentBuilder<
    AdminComponent=Box<dyn Component>,
    BaseComponent=Box<dyn Component>,
>;

impl Component for Box<dyn Component + '_> {
    // ...
    // n.b. be careful to call methods on `*Self` and not `Self`
    // to avoid a recursive call, e.g.
    fn method(&self) {
        (**self).method()
    }
}

Thank you a lot for your answer !

I've already try with Box in function return type, but it didn't work because i missed the + ?Sized !

Does'nt know about this, I will read again the book to better understand

I also have a guide about dyn Trait if you're interested.

1 Like

Perfect, thank you a lot !!! :smiley:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.