Repository: vercel/next.js
File: turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs (Rust)

Code before:
    esm::{EsmExport, EsmExports},
};

#[turbo_tasks::value_trait]
pub trait EcmascriptChunkPlaceable: ChunkableModule + Module {
    #[turbo_tasks::function]
    fn get_exports(self: Vc<Self>) -> Vc<EcmascriptExports>;
    #[turbo_tasks::function]
    fn get_async_module(self: Vc<Self>) -> Vc<OptionAsyncModule> {
        Vc::cell(None)
    }
    /// Returns a split version of this module for the given module part, or self if no
    /// split exists.
    #[turbo_tasks::function]
    fn get_split(
        self: Vc<Self>,
        part: ModulePart,
    ) -> Result<Vc<Box<dyn EcmascriptChunkPlaceable>>> {
        match part {
            ModulePart::Facade
            | ModulePart::Locals
            | ModulePart::RenamedExport { .. }
            | ModulePart::RenamedNamespace { .. } => Ok(self),
            _ => bail!("Unexpected module part: {part:?}"),
        }
    }
}

#[turbo_tasks::value]
enum SideEffectsValue {
    None,
    Constant(bool),
    Glob(ResolvedVc<Glob>),
}

#[turbo_tasks::function]
async fn side_effects_from_package_json(
    package_json: FileSystemPath,
) -> Result<Vc<SideEffectsValue>> {
    let package_json_file = FileSource::new(package_json).to_resolved().await?;
    let package_json = &*package_json_file.content().parse_json().await?;
    if let FileJsonContent::Content(content) = package_json
        && let Some(side_effects) = content.get("sideEffects")
    {
        if let Some(side_effects) = side_effects.as_bool() {
            return Ok(SideEffectsValue::Constant(side_effects).cell());
        } else if let Some(side_effects) = side_effects.as_array() {
            let (globs, issues): (Vec<_>, Vec<_>) = side_effects
                .iter()
                .map(|side_effect| {
                    if let Some(side_effect) = side_effect.as_str() {

Review comment (suggestion):
`get_split` is only called on `EcmascriptModuleAsset`. It doesn't need to be a trait method. It can be a method on `EcmascriptModuleAsset::get_split`.

Code after:

use crate::{
    chunk::EcmascriptChunkItemContent,
    references::{
        async_module::OptionAsyncModule,
        esm::{EsmExport, EsmExports},
    },
};

#[turbo_tasks::value_trait]
pub trait EcmascriptChunkPlaceable: ChunkableModule + Module {
    #[turbo_tasks::function]
    fn get_exports(self: Vc<Self>) -> Vc<EcmascriptExports>;
    #[turbo_tasks::function]
    fn get_async_module(self: Vc<Self>) -> Vc<OptionAsyncModule> {
        Vc::cell(None)
    }

    /// Generate chunk item content directly on the module.
    /// This replaces the need for separate ChunkItem wrapper structs.
    /// The `estimated` parameter is used during size estimation - when true, implementations
    /// should avoid calling chunking context APIs that would cause cycles.
    #[turbo_tasks::function]
    fn chunk_item_content(
        self: Vc<Self>,
        _chunking_context: Vc<Box<dyn ChunkingContext>>,
        _module_graph: Vc<ModuleGraph>,
        _async_module_info: Option<Vc<AsyncModuleInfo>>,
        _estimated: bool,
    ) -> Vc<EcmascriptChunkItemContent>;

    /// Returns the content identity for cache invalidation.
    /// Override this for modules whose content depends on more than just the module source
    /// (e.g., async loaders that depend on available modules).
    #[turbo_tasks::function]
    fn chunk_item_content_ident(
        self: Vc<Self>,
        _chunking_context: Vc<Box<dyn ChunkingContext>>,
        _module_graph: Vc<ModuleGraph>,
    ) -> Vc<AssetIdent> {
        self.ident()
    }

    /// Returns output assets that this chunk item depends on.
    /// Override this for modules that reference static assets, manifests, etc.
    #[turbo_tasks::function]
    fn chunk_item_output_assets(
        self: Vc<Self>,
        _chunking_context: Vc<Box<dyn ChunkingContext>>,
        _module_graph: Vc<ModuleGraph>,
    ) -> Vc<OutputAssetsWithReferenced> {