# Difference between \`LocalDefId\` and \`DefId\`?

**URL:** <https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563>\
**Category:** compiler\
**Created:** [September 13, 2023, 11:58am UTC](https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563 "2023-09-13T11:58:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lem](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lem/32/11183_2.png) [@lem](https://internals.rust-lang.org/u/lem)\
**Post date:** [September 13, 2023, 11:58am UTC](https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563/1 "2023-09-13T11:58:26Z")

</div>

What's the difference between `LocalDefId` and `DefId`?

[When calling `optimized_mir`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/mod.rs#L2369), the argument is given as `DefId` , but when looking at the [actual function implementation](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_transform/src/lib.rs#L583), it seems to accept `LocalDefId` as an argument.

---

<div class="post-metadata">

**Author:** ![wesleywiser](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/wesleywiser/32/2742_2.png) [@wesleywiser](https://internals.rust-lang.org/u/wesleywiser)\
**Post date:** [September 13, 2023, 2:21pm UTC](https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563/2 "2023-09-13T14:21:03Z")

</div>

A `DefId` consists of two parts: an id for a definition (a type definition, a function definition, etc) and a crate id. A `DefId` can refer to items that exist in a dependency crate because the crate id indicates in which crate the item is defined.

A `LocalDefId` is just the definition id and can only refer to items in the local crate (the crate which is currently being compiled).

You can always go from a `LocalDefId` to a `DefId` but it's not always possible to go from a `DefId` to a `LocalDefId` (if the item is defined in a crate which is a dependency of the one being compiled).

The reason that both types exist is that some operations are only valid in the context of the local crate. `Hir` for instance isn't stored in the compilation artifact for dependency crates so [operations](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html) that lookup `Hir` for items use `LocalDefId` instead of `DefId`.

`optimized_mir` is a bit different because there are actually two different implementations of that [query](https://rustc-dev-guide.rust-lang.org/query.html). When `optimized_mir` is called with a `DefId` whose crate id is the [`LOCAL_CRATE`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/constant.LOCAL_CRATE.html), the implementation you found is run. However, when `optimized_mir` is called with a non-local `DefId`, the value is [loaded](https://github.com/rust-lang/rust/blob/735bb7e5df185cc24e56533abd0bbab510931f6f/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs#L219) from the crate metadata on disk.

---

<div class="post-metadata">

**Author:** ![lem](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lem/32/11183_2.png) [@lem](https://internals.rust-lang.org/u/lem)\
**Post date:** [September 14, 2023, 6:52am UTC](https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563/3 "2023-09-14T06:52:34Z")

</div>

Thank you for your kind answer 🙂

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [December 13, 2023, 6:53am UTC](https://internals.rust-lang.org/t/difference-between-localdefid-and-defid/19563/4 "2023-12-13T06:53:19Z")

</div>

Closed on December 13, 2023, 6:53am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
