Difference between `LocalDefId` and `DefId`?

What's the difference between LocalDefId and DefId?

When calling optimized_mir, the argument is given as DefId , but when looking at the actual function implementation, it seems to accept LocalDefId as an argument.

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 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. When optimized_mir is called with a DefId whose crate id is the LOCAL_CRATE, the implementation you found is run. However, when optimized_mir is called with a non-local DefId, the value is loaded from the crate metadata on disk.


Thank you for your kind answer :slight_smile:

1 Like