Repository: servo/servo
File: components/script/module_loading.rs (Rust)

Code before:

    // Step 13. If loadState is not undefined, then:
    // Note: loadState is undefined only in dynamic imports
    let (destination, fetch_client) = match load_state.as_ref() {
        // Step 13.1. Set destination to loadState.[[Destination]].
        // Step 13.2. Set fetchClient to loadState.[[FetchClient]].
        Some(load_state) => (load_state.destination, load_state.fetch_client.clone()),
        None => (
            // Step 11. Let destination be "script".
            Destination::Script,
            // Step 12. Let fetchClient be settingsObject.
            ModuleOwner::DynamicModule(Trusted::new(&global_scope)),
        ),
    };

    let mut cx = unsafe { JSContext::from_ptr(std::ptr::NonNull::new(cx.raw_cx()).unwrap()) };
    let on_single_fetch_complete = move |module_tree: Option<Rc<ModuleTree>>| {
        let cx = &mut cx;
        // Step 1. Let completion be null.
        let completion = match module_tree {
            // Step 2. If moduleScript is null, then set completion to ThrowCompletion(a new TypeError).
            None => Err(gen_type_error(
                &global_scope,
                Error::Type("Module fetching failed".to_string()),
                CanGc::from_cx(cx),
            )),
            Some(module_tree) => {
                // Step 3. Otherwise, if moduleScript's parse error is not null, then:
                // Step 3.1 Let parseError be moduleScript's parse error.
                if let Some(parse_error) = module_tree.get_parse_error() {
                    // Step 3.3 If loadState is not undefined and loadState.[[ErrorToRethrow]] is null,
                    // set loadState.[[ErrorToRethrow]] to parseError.
                    load_state.as_ref().inspect(|load_state| {
                        load_state
                            .error_to_rethrow
                            .borrow_mut()
                            .get_or_insert(parse_error.clone());
                    });

                    // Step 3.2 Set completion to ThrowCompletion(parseError).
                    Err(parse_error.clone())
                } else {
                    // Step 4. Otherwise, set completion to NormalCompletion(moduleScript's record).
                    Ok(module_tree)
                }
            },
        };

        // Step 5. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion).
        finish_loading_imported_module(cx, referrer_module, specifier, payload, completion);
    };

Review comment (suggestion):
Plz do not do this. The closure should either take cx as argument (this might be involved so we can do this in separate PR) or use [`temp_cx`](https://github.com/servo/servo/blob/de7c9d2e4314820bd603af98d938b15a9b6a79e5/components/script_bindings/script_runtime.rs#L85) in closure body so we can clearly know what still needs to be done.

Code after:
    };

    // Step 10. Let fetchOptions be the result of getting the descendant script fetch options given
    // originalFetchOptions, url, and settingsObject.
    let fetch_options = original_fetch_options.descendant_fetch_options();

    // Step 13. If loadState is not undefined, then:
    // Note: loadState is undefined only in dynamic imports
    let (destination, fetch_client) = match load_state.as_ref() {
        // Step 13.1. Set destination to loadState.[[Destination]].
        // Step 13.2. Set fetchClient to loadState.[[FetchClient]].
        Some(load_state) => (load_state.destination, load_state.fetch_client.clone()),
        None => (
            // Step 11. Let destination be "script".
            Destination::Script,
            // Step 12. Let fetchClient be settingsObject.
            ModuleOwner::DynamicModule(Trusted::new(&global_scope)),
        ),
    };

    let on_single_fetch_complete = move |module_tree: Option<Rc<ModuleTree>>| {
        let mut cx = unsafe { script_bindings::script_runtime::temp_cx() };
        let mut realm = CurrentRealm::assert(&mut cx);
        let cx = &mut realm;

        // Step 1. Let completion be null.
        let completion = match module_tree {
            // Step 2. If moduleScript is null, then set completion to ThrowCompletion(a new TypeError).
            None => Err(gen_type_error(
                &global_scope,
                Error::Type("Module fetching failed".to_string()),
                CanGc::from_cx(cx),
            )),
            Some(module_tree) => {
                // Step 3. Otherwise, if moduleScript's parse error is not null, then:
                // Step 3.1 Let parseError be moduleScript's parse error.
                if let Some(parse_error) = module_tree.get_parse_error() {
                    // Step 3.3 If loadState is not undefined and loadState.[[ErrorToRethrow]] is null,
                    // set loadState.[[ErrorToRethrow]] to parseError.
                    load_state.as_ref().inspect(|load_state| {
                        load_state
                            .error_to_rethrow
                            .borrow_mut()
                            .get_or_insert(parse_error.clone());
                    });

                    // Step 3.2 Set completion to ThrowCompletion(parseError).
                    Err(parse_error.clone())
                } else {
                    // Step 4. Otherwise, set completion to NormalCompletion(moduleScript's record).
                    Ok(module_tree)