rust-lang/rust · error

failed to find foreign module

Error message

failed to find foreign module

What it means

Fires in the `native_library` query provider (cstore_impl.rs:450). When resolving a foreign (FFI) item, the provider looks up the item's `foreign_module` id in the crate's `foreign_modules` map and `.expect("failed to find foreign module")` panics if it is absent. The invariant is that every foreign item's module id appears in the collected `foreign_modules` map for its crate.

Source

Thrown at compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs:450

}

pub(in crate::rmeta) fn provide(providers: &mut Providers) {
    provide_cstore_hooks(providers);
    providers.queries = rustc_middle::query::Providers {
        allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
        alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
        is_private_dep: |_tcx, LocalCrate| false,
        native_library: |tcx, id| {
            tcx.native_libraries(id.krate)
                .iter()
                .filter(|lib| native_libs::relevant_lib(tcx.sess, lib))
                .find(|lib| {
                    let Some(fm_id) = lib.foreign_module else {
                        return false;
                    };
                    let map = tcx.foreign_modules(id.krate);
                    map.get(&fm_id)
                        .expect("failed to find foreign module")
                        .foreign_items
                        .contains(&id)
                })
        },
        native_libraries: native_libs::collect,
        foreign_modules: foreign_modules::collect,
        externally_implementable_items: eii::collect,

        // Returns a map from a sufficiently visible external item (i.e., an
        // external item that is visible from at least one local module) to a
        // sufficiently visible parent (considering modules that re-export the
        // external item to be parents).
        visible_parent_map: |tcx, ()| {
            use std::collections::hash_map::Entry;
            use std::collections::vec_deque::VecDeque;

            let mut visible_parent_map: DefIdMap<DefId> = Default::default();
            // This is a secondary visible_parent_map, storing the DefId of

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. `cargo clean` and rebuild so `native_libraries` and `foreign_modules` are collected consistently for the current cfg/link config.
  2. Re-run build scripts (`touch build.rs` or `cargo clean -p <crate>`) so `cargo:rustc-link-lib`/`native=` directives are regenerated.
  3. Verify the FFI block's `#[link(name = ...)]` / `extern "C"` module matches a library actually passed via `-L native`.
  4. Clean-build ICE -> file an issue; a foreign item's module id was not present in the foreign_modules map.
Defensive patterns

Strategy: validation

Validate before calling

# Regenerate native-library/foreign-module collection after link changes
touch build.rs 2>/dev/null || true
cargo clean -p <crate-with-ffi>
cargo build

Try / catch

cargo build || { cargo clean -p $(cargo metadata --no-deps --format-version=1 | jq -r '.packages[].name') && cargo build; }

Prevention

When it happens

Trigger: An FFI item (`extern "C" { ... }` or `extern { ... }`) references a `foreign_module` id that was not emitted by `foreign_modules::collect` for that crate; mismatch between `native_libraries` and `foreign_modules` collection; metadata for a dependency built with a different native-module encoding.

Common situations: A `-L native=...` / `--extern` linking change reusing stale metadata; cross-version reuse of a crate that does FFI; build-script-generated `cargo:rustc-link-lib` directives changed while `target/` was reused; incomplete native-lib collection due to cfg differences.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/e2b215bf1b30214e. Report an issue: GitHub.