Expand description
HIR (previously known as descriptors) provides a high-level object oriented access to Rust code.
The principal difference between HIR and syntax trees is that HIR is bound to a particular crate instance. That is, it has cfg flags and features applied. So, the relation between syntax and HIR is many-to-one.
HIR is the public API of the all of the compiler logic above syntax trees. It is written in “OO” style. Each type is self contained (as in, it knows it’s parents and full context). It should be “clean code”.
hir_*
crates are the implementation of the compiler logic.
They are written in “ECS” style, with relatively little abstractions.
Many types are not self-contained, and explicitly use local indexes, arenas, etc.
hir
is what insulates the “we don’t know how to actually write an incremental compiler”
from the ide with completions, hovers, etc. It is a (soft, internal) boundary:
https://www.tedinski.com/2018/02/06/system-boundaries.html.
Re-exports
pub use crate::diagnostics::AnyDiagnostic;
pub use crate::diagnostics::BreakOutsideOfLoop;
pub use crate::diagnostics::InactiveCode;
pub use crate::diagnostics::InvalidDeriveTarget;
pub use crate::diagnostics::MacroError;
pub use crate::diagnostics::MalformedDerive;
pub use crate::diagnostics::MismatchedArgCount;
pub use crate::diagnostics::MissingFields;
pub use crate::diagnostics::MissingMatchArms;
pub use crate::diagnostics::MissingUnsafe;
pub use crate::diagnostics::NoSuchField;
pub use crate::diagnostics::PrivateAssocItem;
pub use crate::diagnostics::PrivateField;
pub use crate::diagnostics::ReplaceFilterMapNextWithFindMap;
pub use crate::diagnostics::TypeMismatch;
pub use crate::diagnostics::UnimplementedBuiltinMacro;
pub use crate::diagnostics::UnresolvedExternCrate;
pub use crate::diagnostics::UnresolvedImport;
pub use crate::diagnostics::UnresolvedMacroCall;
pub use crate::diagnostics::UnresolvedModule;
pub use crate::diagnostics::UnresolvedProcMacro;
Modules
hir
. This breaks abstraction boundary a bit, it would be cool if
we didn’t do that.hir
don’t have to depend on
low-level crates.Structs
#[attr]
vs #[attr(...)]
vs #[attr = ...]
) is considered now.cfg
attributes.
We have two kind of options in different namespaces: atomic options like unix
, and
key-value options like target_arch="x86"
.FileId
and contains source code. However, another source of source code in
Rust are macros: each macro can be thought of as producing a “temporary
file”. To assign an id to such a file, we use the id of the macro call that
produced the file. So, a HirFileId
is either a FileId
(source code
written by user), or a MacroCallId
(source code produced by macro).InFile<T>
stores a value of T
inside a particular file/syntax tree.Name
is a wrapper around string, which is used in hir for both references
and declarations. In theory, names should also carry hygiene info, but we are
not there yet!SemanticScope
encapsulates the notion of a scope (the set of visible
names) at a particular program point.Enums
inner.as_assoc_item(db).is_some()
We do not actively enforce this invariant.