Repository: rust-analyzer/rust-analyzer
Pull request #633 (2019-01-24 23:09:53)

use ToOwned trait instead of inherent method


Patch:
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 9825d52cfc..b5d63e8201 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -160,7 +160,6 @@ pub trait FilesDatabase: salsa::Database {
     /// Contents of the source root.
     #[salsa::input]
     fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>;
-    fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>;
     /// The set of "local" (that is, from the current workspace) roots.
     /// Files in local roots are assumed to change frequently.
     #[salsa::input]
@@ -174,17 +173,6 @@ pub trait FilesDatabase: salsa::Database {
     fn crate_graph(&self) -> Arc<CrateGraph>;
 }
 
-fn source_root_crates(db: &impl FilesDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> {
-    let root = db.source_root(id);
-    let graph = db.crate_graph();
-    let res = root
-        .files
-        .values()
-        .filter_map(|&it| graph.crate_id_for_crate_root(it))
-        .collect::<Vec<_>>();
-    Arc::new(res)
-}
-
 #[cfg(test)]
 mod tests {
     use super::{CrateGraph, FileId, SmolStr};
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs
index 84759c75af..32d7e09b99 100644
--- a/crates/ra_db/src/lib.rs
+++ b/crates/ra_db/src/lib.rs
@@ -13,7 +13,7 @@ pub use crate::{
     cancellation::Canceled,
     input::{
         FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
-        FileTextQuery, FileSourceRootQuery, SourceRootQuery, SourceRootCratesQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
+        FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
         FileRelativePathQuery
     },
     loc2id::LocationIntener,
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 6b13b464d2..ab1c428db7 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -3,35 +3,25 @@
 
 use std::sync::Arc;
 
-use ra_syntax::ast::{self, NameOwner, StructFlavor};
+use ra_syntax::{
+    SyntaxNode,
+    ast::{self, NameOwner, StructFlavor, AstNode}
+};
 
 use crate::{
-    Name, AsName, Struct, Enum, EnumVariant, Crate,
-    HirDatabase,
+    DefId, DefLoc, Name, AsName, Struct, Enum, EnumVariant,
+    HirDatabase, DefKind,
+    SourceItemId,
     type_ref::TypeRef,
-    ids::LocationCtx,
 };
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum AdtDef {
-    Struct(Struct),
-    Enum(Enum),
-}
-impl_froms!(AdtDef: Struct, Enum);
-
-impl AdtDef {
-    pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
-        match self {
-            AdtDef::Struct(s) => s.module(db),
-            AdtDef::Enum(e) => e.module(db),
-        }
-        .krate(db)
+impl Struct {
+    pub(crate) fn new(def_id: DefId) -> Self {
+        Struct { def_id }
     }
-}
 
-impl Struct {
     pub(crate) fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
-        db.struct_data((*self).into()).variant_data.clone()
+        db.struct_data(self.def_id).variant_data.clone()
     }
 }
 
@@ -49,12 +39,38 @@ impl StructData {
         StructData { name, variant_data }
     }
 
-    pub(crate) fn struct_data_query(db: &impl HirDatabase, struct_: Struct) -> Arc<StructData> {
-        let (_, struct_def) = struct_.source(db);
-        Arc::new(StructData::new(&*struct_def))
+    pub(crate) fn struct_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<StructData> {
+        let def_loc = def_id.loc(db);
+        assert!(def_loc.kind == DefKind::Struct);
+        let syntax = db.file_item(def_loc.source_item_id);
+        let struct_def =
+            ast::StructDef::cast(&syntax).expect("struct def should point to StructDef node");
+        Arc::new(StructData::new(struct_def))
     }
 }
 
+fn get_def_id(
+    db: &impl HirDatabase,
+    same_file_loc: &DefLoc,
+    node: &SyntaxNode,
+    expected_kind: DefKind,
+) -> DefId {
+    let file_id = same_file_loc.source_item_id.file_id;
+    let file_items = db.file_items(file_id);
+
+    let item_id = file_items.id_of(file_id, node);
+    let source_item_id = SourceItemId {
+        item_id: Some(item_id),
+        ..same_file_loc.source_item_id
+    };
+    let loc = DefLoc {
+        kind: expected_kind,
+        source_item_id,
+        ..*same_file_loc
+    };
+    loc.id(db)
+}
+
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct EnumData {
     pub(crate) name: Option<Name>,
@@ -67,24 +83,27 @@ impl EnumData {
         EnumData { name, variants }
     }
 
-    pub(crate) fn enum_data_query(db: &impl HirDatabase, e: Enum) -> Arc<EnumData> {
-        let (file_id, enum_def) = e.source(db);
-        let module = e.module(db);
-        let ctx = LocationCtx::new(db, module, file_id);
+    pub(crate) fn enum_data_query(db: &impl HirDatabase, def_id: DefId) -> Arc<EnumData> {
+        let def_loc = def_id.loc(db);
+        assert!(def_loc.kind == DefKind::Enum);
+        let syntax = db.file_item(def_loc.source_item_id);
+        let enum_def = ast::EnumDef::cast(&syntax).expect("enum def should point to EnumDef node");
         let variants = if let Some(vl) = enum_def.variant_list() {
             vl.variants()
                 .filter_map(|variant_def| {
-                    let name = variant_def.name()?.as_name();
-                    let var = EnumVariant {
-                        id: ctx.to_def(variant_def),
-                    };
-                    Some((name, var))
+                    let name = variant_def.name().map(|n| n.as_name());
+
+                    name.map(|n| {
+                        let def_id =
+                            get_def_id(db, &def_loc, variant_def.syntax(), DefKind::EnumVariant);
+                        (n, EnumVariant::new(def_id))
+                    })
                 })
                 .collect()
         } else {
             Vec::new()
         };
-        Arc::new(EnumData::new(&*enum_def, variants))
+        Arc::new(EnumData::new(enum_def, variants))
     }
 }
 
@@ -109,15 +128,21 @@ impl EnumVariantData {
 
     pub(crate) fn enum_variant_data_query(
         db: &impl HirDatabase,
-        var: EnumVariant,
+        def_id: DefId,
     ) -> Arc<EnumVariantData> {
-        let (file_id, variant_def) = var.source(db);
-        let enum_def = variant_def.parent_enum();
-        let ctx = LocationCtx::new(db, var.module(db), file_id);
-        let e = Enum {
-            id: ctx.to_def(enum_def),
-        };
-        Arc::new(EnumVariantData::new(&*variant_def, e))
+        let def_loc = def_id.loc(db);
+        assert!(def_loc.kind == DefKind::EnumVariant);
+        let syntax = db.file_item(def_loc.source_item_id);
+        let variant_def = ast::EnumVariant::cast(&syntax)
+            .expect("enum variant def should point to EnumVariant node");
+        let enum_node = syntax
+            .parent()
+            .expect("enum variant should have enum variant list ancestor")
+            .parent()
+            .expect("enum variant list should have enum ancestor");
+        let enum_def_id = get_def_id(db, &def_loc, enum_node, DefKind::Enum);
+
+        Arc::new(EnumVariantData::new(variant_def, Enum::new(enum_def_id)))
     }
 }
 
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 6739627b4e..3ff07bd60c 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -5,23 +5,22 @@ use ra_db::{CrateId, FileId};
 use ra_syntax::{ast::self, TreeArc, SyntaxNode};
 
 use crate::{
-    Name, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId,
+    Name, DefId, Path, PerNs, ScopesWithSyntaxMapping, Ty, HirFileId,
     type_ref::TypeRef,
     nameres::{ModuleScope, lower::ImportId},
     db::HirDatabase,
     expr::BodySyntaxMapping,
-    ty::{InferenceResult, VariantDef},
+    ty::InferenceResult,
     adt::VariantData,
     generics::GenericParams,
-    docs::{Documentation, Docs, docs_from_ast},
-    module_tree::ModuleId,
-    ids::{FunctionId, StructId, EnumId, EnumVariantId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
+    code_model_impl::def_id_to_ast,
+    docs::{Documentation, Docs, docs_from_ast}
 };
 
 /// hir::Crate describes a single crate. It's the main interface with which
 /// a crate's dependencies interact. Mostly, it should be just a proxy for the
 /// root module.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Crate {
     pub(crate) crate_id: CrateId,
 }
@@ -46,40 +45,22 @@ impl Crate {
 
 #[derive(Debug)]
 pub enum Def {
-    Item,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Module {
-    pub(crate) krate: CrateId,
-    pub(crate) module_id: ModuleId,
-}
-
-/// The defs which can be visible in the module.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum ModuleDef {
     Module(Module),
-    Function(Function),
     Struct(Struct),
     Enum(Enum),
-    // Can't be directly declared, but can be imported.
     EnumVariant(EnumVariant),
+    Function(Function),
     Const(Const),
     Static(Static),
     Trait(Trait),
     Type(Type),
+    Item,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Module {
+    pub(crate) def_id: DefId,
 }
-impl_froms!(
-    ModuleDef: Module,
-    Function,
-    Struct,
-    Enum,
-    EnumVariant,
-    Const,
-    Static,
-    Trait,
-    Type
-);
 
 pub enum ModuleSource {
     SourceFile(TreeArc<ast::SourceFile>),
@@ -168,7 +149,7 @@ impl Module {
         self.scope_impl(db)
     }
 
-    pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
+    pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> {
         self.resolve_path_impl(db, path)
     }
 
@@ -179,7 +160,7 @@ impl Module {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StructField {
-    parent: VariantDef,
+    parent: DefId,
     name: Name,
 }
 
@@ -193,38 +174,38 @@ impl StructField {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Struct {
-    pub(crate) id: StructId,
+    pub(crate) def_id: DefId,
 }
 
 impl Struct {
-    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
-        self.id.source(db)
-    }
-
-    pub fn module(&self, db: &impl HirDatabase) -> Module {
-        self.id.module(db)
+    pub fn def_id(&self) -> DefId {
+        self.def_id
     }
 
     pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
-        db.struct_data(*self).name.clone()
+        db.struct_data(self.def_id).name.clone()
     }
 
     pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> {
-        db.struct_data(*self)
+        db.struct_data(self.def_id)
             .variant_data
             .fields()
             .iter()
             .map(|it| StructField {
-                parent: (*self).into(),
+                parent: self.def_id,
                 name: it.name.clone(),
             })
             .collect()
     }
 
+    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
+        def_id_to_ast(db, self.def_id)
+    }
+
     pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
-        db.generic_params((*self).into())
+        db.generic_params(self.def_id)
     }
 }
 
@@ -234,30 +215,34 @@ impl Docs for Struct {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Enum {
-    pub(crate) id: EnumId,
+    pub(crate) def_id: DefId,
 }
 
 impl Enum {
-    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
-        self.id.source(db)
+    pub(crate) fn new(def_id: DefId) -> Self {
+        Enum { def_id }
     }
 
-    pub fn module(&self, db: &impl HirDatabase) -> Module {
-        self.id.module(db)
+    pub fn def_id(&self) -> DefId {
+        self.def_id
     }
 
     pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
-        db.enum_data(*self).name.clone()
+        db.enum_data(self.def_id).name.clone()
     }
 
     pub fn variants(&self, db: &impl HirDatabase) -> Vec<(Name, EnumVariant)> {
-        db.enum_data(*self).variants.clone()
+        db.enum_data(self.def_id).variants.clone()
+    }
+
+    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
+        def_id_to_ast(db, self.def_id)
     }
 
     pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
-        db.generic_params((*self).into())
+        db.generic_params(self.def_id)
     }
 }
 
@@ -267,28 +252,30 @@ impl Docs for Enum {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumVariant {
-    pub(crate) id: EnumVariantId,
+    pub(crate) def_id: DefId,
 }
 
 impl EnumVariant {
-    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) {
-        self.id.source(db)
+    pub(crate) fn new(def_id: DefId) -> Self {
+        EnumVariant { def_id }
     }
-    pub fn module(&self, db: &impl HirDatabase) -> Module {
-        self.id.module(db)
+
+    pub fn def_id(&self) -> DefId {
+        self.def_id
     }
+
     pub fn parent_enum(&self, db: &impl HirDatabase) -> Enum {
-        db.enum_variant_data(*self).parent_enum.clone()
+        db.enum_variant_data(self.def_id).parent_enum.clone()
     }
 
     pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
-        db.enum_variant_data(*self).name.clone()
+        db.enum_variant_data(self.def_id).name.clone()
     }
 
     pub fn variant_data(&self, db: &impl HirDatabase) -> Arc<VariantData> {
-        db.enum_variant_data(*self).variant_data.clone()
+        db.enum_variant_data(self.def_id).variant_data.clone()
     }
 
     pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> {
@@ -296,11 +283,15 @@ impl EnumVariant {
             .fields()
             .iter()
             .map(|it| StructField {
-                parent: (*self).into(),
+                parent: self.def_id,
                 name: it.name.clone(),
             })
             .collect()
     }
+
+    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::EnumVariant>) {
+        def_id_to_ast(db, self.def_id)
+    }
 }
 
 impl Docs for EnumVariant {
@@ -309,9 +300,9 @@ impl Docs for EnumVariant {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Function {
-    pub(crate) id: FunctionId,
+    pub(crate) def_id: DefId,
 }
 
 pub use crate::code_model_impl::function::ScopeEntryWithSyntax;
@@ -348,21 +339,21 @@ impl FnSignature {
 }
 
 impl Function {
-    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
-        self.id.source(db)
+    pub fn def_id(&self) -> DefId {
+        self.def_id
     }
 
-    pub fn module(&self, db: &impl HirDatabase) -> Module {
-        self.id.module(db)
+    pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
+        def_id_to_ast(db, self.def_id)
     }
 
     pub fn body_syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> {
-        db.body_syntax_mapping(*self)
+        db.body_syntax_mapping(self.def_id)
     }
 
     pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping {
-        let scopes = db.fn_scopes(*self);
-        let syntax_mapping = db.body_syntax_mapping(*self);
+        let scopes = db.fn_scopes(self.def_id);
+        let syntax_mapping = db.body_syntax_mapping(self.def_id);
         ScopesWithSyntaxMapping {
             scopes,
             syntax_mapping,
@@ -370,15 +361,15 @@ impl Function {
     }
 
     pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
-        db.fn_signature(*self)
+        db.fn_signature(self.def_id)
     }
 
     pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
-        db.infer(*self)
+        db.infer(self.def_id)
     }
 
     pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
-        db.generic_params((*self).into())
+        db.generic_params(self.def_id)
     }
 }
 
@@ -388,14 +379,18 @@ impl Docs for Function {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Const {
-    pub(crate) id: ConstId,
+    pub(crate) def_id: DefId,
 }
 
 impl Const {
+    pub(crate) fn new(def_id: DefId) -> Const {
+        Const { def_id }
+    }
+
     pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) {
-        self.id.source(db)
+        def_id_to_ast(db, self.def_id)
     }
 }
 
@@ -405,14 +400,18 @@ impl Docs for Const {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Static {
-    pub(crate) id: StaticId,
+    pub(crate) def_id: DefId,
 }
 
 impl Static {
+    pub(crate) fn new(def_id: DefId) -> Static {
+        Static { def_id }
+    }
+
     pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) {
-        self.id.source(db)
+        def_id_to_ast(db, self.def_id)
     }
 }
 
@@ -422,18 +421,22 @@ impl Docs for Static {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Trait {
-    pub(crate) id: TraitId,
+    pub(crate) def_id: DefId,
 }
 
 impl Trait {
+    pub(crate) fn new(def_id: DefId) -> Trait {
+        Trait { def_id }
+    }
+
     pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TraitDef>) {
-        self.id.source(db)
+        def_id_to_ast(db, self.def_id)
     }
 
     pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
-        db.generic_params((*self).into())
+        db.generic_params(self.def_id)
     }
 }
 
@@ -443,18 +446,22 @@ impl Docs for Trait {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Type {
-    pub(crate) id: TypeId,
+    pub(crate) def_id: DefId,
 }
 
 impl Type {
+    pub(crate) fn new(def_id: DefId) -> Type {
+        Type { def_id }
+    }
+
     pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, TreeArc<ast::TypeDef>) {
-        self.id.source(db)
+        def_id_to_ast(db, self.def_id)
     }
 
     pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
-        db.generic_params((*self).into())
+        db.generic_params(self.def_id)
     }
 }
 
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs
index 1f28fab748..0cea9f7b6f 100644
--- a/crates/ra_hir/src/code_model_impl.rs
+++ b/crates/ra_hir/src/code_model_impl.rs
@@ -1,3 +1,18 @@
 mod krate; // `crate` is invalid ident :(
 mod module;
 pub(crate) mod function;
+
+use ra_syntax::{AstNode, TreeArc};
+
+use crate::{HirDatabase, DefId, HirFileId};
+
+pub(crate) fn def_id_to_ast<N: AstNode>(
+    db: &impl HirDatabase,
+    def_id: DefId,
+) -> (HirFileId, TreeArc<N>) {
+    let (file_id, syntax) = def_id.source(db);
+    let ast = N::cast(&syntax)
+        .unwrap_or_else(|| panic!("def points to wrong source {:?} {:?}", def_id, syntax))
+        .to_owned();
+    (file_id, ast)
+}
diff --git a/crates/ra_hir/src/code_model_impl/function.rs b/crates/ra_hir/src/code_model_impl/function.rs
index e0dd4d6290..c68c6bfbf0 100644
--- a/crates/ra_hir/src/code_model_impl/function.rs
+++ b/crates/ra_hir/src/code_model_impl/function.rs
@@ -2,32 +2,41 @@ mod scope;
 
 use std::sync::Arc;
 
-use ra_syntax::ast::{self, NameOwner};
+use ra_syntax::{TreeArc, ast::{self, NameOwner}};
 
 use crate::{
-    HirDatabase, Name, AsName, Function, FnSignature,
+    DefId, HirDatabase, Name, AsName, Function, FnSignature, Module,
     type_ref::{TypeRef, Mutability},
     expr::Body,
     impl_block::ImplBlock,
+    code_model_impl::def_id_to_ast,
 };
 
 pub use self::scope::{FnScopes, ScopesWithSyntaxMapping, ScopeEntryWithSyntax};
 
 impl Function {
+    pub(crate) fn new(def_id: DefId) -> Function {
+        Function { def_id }
+    }
+
     pub(crate) fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
-        db.body_hir(*self)
+        db.body_hir(self.def_id)
+    }
+
+    pub(crate) fn module(&self, db: &impl HirDatabase) -> Module {
+        self.def_id.module(db)
     }
 
     /// The containing impl block, if this is a method.
     pub(crate) fn impl_block(&self, db: &impl HirDatabase) -> Option<ImplBlock> {
-        let module_impls = db.impls_in_module(self.module(db));
-        ImplBlock::containing(module_impls, (*self).into())
+        self.def_id.impl_block(db)
     }
 }
 
 impl FnSignature {
-    pub(crate) fn fn_signature_query(db: &impl HirDatabase, func: Function) -> Arc<FnSignature> {
-        let (_, node) = func.source(db);
+    pub(crate) fn fn_signature_query(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
+        // FIXME: we're using def_id_to_ast here to avoid returning Cancelable... this is a bit hacky
+        let node: TreeArc<ast::FnDef> = def_id_to_ast(db, def_id).1;
         let name = node
             .name()
             .map(|n| n.as_name())
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs
index cdd30b402c..8c6e34873b 100644
--- a/crates/ra_hir/src/code_model_impl/krate.rs
+++ b/crates/ra_hir/src/code_model_impl/krate.rs
@@ -1,7 +1,7 @@
 use ra_db::CrateId;
 
 use crate::{
-    Crate, CrateDependency, AsName, Module,
+    HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId,
     db::HirDatabase,
 };
 
@@ -21,13 +21,27 @@ impl Crate {
             .collect()
     }
     pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> {
-        let module_tree = db.module_tree(self.crate_id);
-        let module_id = module_tree.modules().next()?;
+        let crate_graph = db.crate_graph();
+        let file_id = crate_graph.crate_root(self.crate_id);
+        let source_root_id = db.file_source_root(file_id);
+        let file_id = HirFileId::from(file_id);
+        let module_tree = db.module_tree(source_root_id);
+        // FIXME: teach module tree about crate roots instead of guessing
+        let source = SourceItemId {
+            file_id,
+            item_id: None,
+        };
+        let module_id = module_tree.find_module_by_source(source)?;
 
-        let module = Module {
-            krate: self.crate_id,
+        let def_loc = DefLoc {
+            kind: DefKind::Module,
+            source_root_id,
             module_id,
+            source_item_id: module_id.source(&module_tree),
         };
+        let def_id = def_loc.id(db);
+
+        let module = Module::new(def_id);
         Some(module)
     }
 }
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 6419d3934c..d94079f11c 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -1,33 +1,52 @@
-use ra_db::FileId;
-use ra_syntax::{ast, SyntaxNode, TreeArc};
+use ra_db::{SourceRootId, FileId};
+use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc};
 
 use crate::{
-    Module, ModuleSource, Problem, ModuleDef,
-    Crate, Name, Path, PathKind, PerNs,
+    Module, ModuleSource, Problem,
+    Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def,
     module_tree::ModuleId,
     nameres::{ModuleScope, lower::ImportId},
     db::HirDatabase,
 };
 
 impl Module {
-    fn with_module_id(&self, module_id: ModuleId) -> Module {
-        Module {
+    pub(crate) fn new(def_id: DefId) -> Self {
+        crate::code_model_api::Module { def_id }
+    }
+
+    pub(crate) fn from_module_id(
+        db: &impl HirDatabase,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
+    ) -> Self {
+        let module_tree = db.module_tree(source_root_id);
+        let def_loc = DefLoc {
+            kind: DefKind::Module,
+            source_root_id,
             module_id,
-            krate: self.krate,
-        }
+            source_item_id: module_id.source(&module_tree),
+        };
+        let def_id = def_loc.id(db);
+        Module::new(def_id)
     }
 
     pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
-        let module_tree = db.module_tree(self.krate);
-        let link = self.module_id.parent_link(&module_tree)?;
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let link = loc.module_id.parent_link(&module_tree)?;
         Some(link.name(&module_tree).clone())
     }
 
     pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) {
-        let module_tree = db.module_tree(self.krate);
-        let source = self.module_id.source(&module_tree);
-        let module_source = ModuleSource::from_source_item_id(db, source);
-        let file_id = source.file_id.as_original_file();
+        let loc = self.def_id.loc(db);
+        let file_id = loc.source_item_id.file_id.as_original_file();
+        let syntax_node = db.file_item(loc.source_item_id);
+        let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) {
+            ModuleSource::SourceFile(source_file.to_owned())
+        } else {
+            let module = ast::Module::cast(&syntax_node).unwrap();
+            ModuleSource::Module(module.to_owned())
+        };
         (file_id, module_source)
     }
 
@@ -35,8 +54,9 @@ impl Module {
         &self,
         db: &impl HirDatabase,
     ) -> Option<(FileId, TreeArc<ast::Module>)> {
-        let module_tree = db.module_tree(self.krate);
-        let link = self.module_id.parent_link(&module_tree)?;
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let link = loc.module_id.parent_link(&module_tree)?;
         let file_id = link
             .owner(&module_tree)
             .source(&module_tree)
@@ -51,67 +71,85 @@ impl Module {
         db: &impl HirDatabase,
         import: ImportId,
     ) -> TreeArc<ast::PathSegment> {
-        let source_map = db.lower_module_source_map(self.clone());
+        let loc = self.def_id.loc(db);
+        let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id);
         let (_, source) = self.definition_source(db);
         source_map.get(&source, import)
     }
 
-    pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> {
-        Some(Crate::new(self.krate))
+    pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> {
+        let root = self.crate_root(db);
+        let loc = root.def_id.loc(db);
+        let file_id = loc.source_item_id.file_id.as_original_file();
+
+        let crate_graph = db.crate_graph();
+        let crate_id = crate_graph.crate_id_for_crate_root(file_id)?;
+        Some(Crate::new(crate_id))
     }
 
     pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module {
-        let module_tree = db.module_tree(self.krate);
-        let module_id = self.module_id.crate_root(&module_tree);
-        self.with_module_id(module_id)
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let module_id = loc.module_id.crate_root(&module_tree);
+        Module::from_module_id(db, loc.source_root_id, module_id)
     }
 
     /// Finds a child module with the specified name.
     pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
-        let module_tree = db.module_tree(self.krate);
-        let child_id = self.module_id.child(&module_tree, name)?;
-        Some(self.with_module_id(child_id))
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let child_id = loc.module_id.child(&module_tree, name)?;
+        Some(Module::from_module_id(db, loc.source_root_id, child_id))
     }
 
     /// Iterates over all child modules.
     pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> {
-        let module_tree = db.module_tree(self.krate);
-        let children = self
+        // FIXME this should be implementable without collecting into a vec, but
+        // it's kind of hard since the iterator needs to keep a reference to the
+        // module tree.
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let children = loc
             .module_id
             .children(&module_tree)
-            .map(|(_, module_id)| self.with_module_id(module_id))
+            .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id))
             .collect::<Vec<_>>();
         children.into_iter()
     }
 
     pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> {
-        let module_tree = db.module_tree(self.krate);
-        let parent_id = self.module_id.parent(&module_tree)?;
-        Some(self.with_module_id(parent_id))
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        let parent_id = loc.module_id.parent(&module_tree)?;
+        Some(Module::from_module_id(db, loc.source_root_id, parent_id))
     }
 
     /// Returns a `ModuleScope`: a set of items, visible in this module.
     pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope {
-        let item_map = db.item_map(self.krate);
-        item_map.per_module[&self.module_id].clone()
+        let loc = self.def_id.loc(db);
+        let item_map = db.item_map(loc.source_root_id);
+        item_map.per_module[&loc.module_id].clone()
     }
 
-    pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
-        let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind {
-            PathKind::Crate => self.crate_root(db).into(),
-            PathKind::Self_ | PathKind::Plain => self.clone().into(),
-            PathKind::Super => {
-                if let Some(p) = self.parent(db) {
-                    p.into()
-                } else {
+    pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> {
+        let mut curr_per_ns = PerNs::types(
+            match path.kind {
+                PathKind::Crate => self.crate_root(db),
+                PathKind::Self_ | PathKind::Plain => self.clone(),
+                PathKind::Super => {
+                    if let Some(p) = self.parent(db) {
+                        p
+                    } else {
+                        return PerNs::none();
+                    }
+                }
+                PathKind::Abs => {
+                    // TODO: absolute use is not supported
                     return PerNs::none();
                 }
             }
-            PathKind::Abs => {
-                // TODO: absolute use is not supported
-                return PerNs::none();
-            }
-        });
+            .def_id,
+        );
 
         for segment in path.segments.iter() {
             let curr = match curr_per_ns.as_ref().take_types() {
@@ -126,16 +164,15 @@ impl Module {
                 }
             };
             // resolve segment in curr
-
-            curr_per_ns = match curr {
-                ModuleDef::Module(m) => {
+            curr_per_ns = match curr.resolve(db) {
+                Def::Module(m) => {
                     let scope = m.scope(db);
                     match scope.get(&segment.name) {
-                        Some(r) => r.def_id.clone(),
+                        Some(r) => r.def_id,
                         None => PerNs::none(),
                     }
                 }
-                ModuleDef::Enum(e) => {
+                Def::Enum(e) => {
                     // enum variant
                     let matching_variant = e
                         .variants(db)
@@ -143,7 +180,7 @@ impl Module {
                         .find(|(n, _variant)| n == &segment.name);
 
                     match matching_variant {
-                        Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()),
+                        Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()),
                         None => PerNs::none(),
                     }
                 }
@@ -162,7 +199,8 @@ impl Module {
         &self,
         db: &impl HirDatabase,
     ) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
-        let module_tree = db.module_tree(self.krate);
-        self.module_id.problems(&module_tree, db)
+        let loc = self.def_id.loc(db);
+        let module_tree = db.module_tree(loc.source_root_id);
+        loc.module_id.problems(&module_tree, db)
     }
 }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 5304f5d313..cc03da1e25 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -1,21 +1,20 @@
 use std::sync::Arc;
 
 use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
-use ra_db::{SyntaxDatabase, CrateId, salsa};
+use ra_db::{SourceRootId, SyntaxDatabase, salsa};
 
 use crate::{
-    MacroCallId, Name, HirFileId,
-    SourceFileItems, SourceItemId, Crate, Module, HirInterner,
+    HirInterner, DefId, MacroCallId, Name, HirFileId,
+    SourceFileItems, SourceItemId, Crate,
     query_definitions,
-    Function, FnSignature, FnScopes,
-    Struct, Enum, EnumVariant,
+    FnSignature, FnScopes,
     macros::MacroExpansion,
-    module_tree::ModuleTree,
+    module_tree::{ModuleId, ModuleTree},
     nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
-    ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, VariantDef},
+    ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks},
     adt::{StructData, EnumData, EnumVariantData},
     impl_block::ModuleImplBlocks,
-    generics::{GenericParams, GenericDef},
+    generics::GenericParams,
 };
 
 #[salsa::query_group]
@@ -27,25 +26,25 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
     fn expand_macro_invocation(&self, invoc: MacroCallId) -> Option<Arc<MacroExpansion>>;
 
     #[salsa::invoke(query_definitions::fn_scopes)]
-    fn fn_scopes(&self, func: Function) -> Arc<FnScopes>;
+    fn fn_scopes(&self, def_id: DefId) -> Arc<FnScopes>;
 
     #[salsa::invoke(crate::adt::StructData::struct_data_query)]
-    fn struct_data(&self, s: Struct) -> Arc<StructData>;
+    fn struct_data(&self, def_id: DefId) -> Arc<StructData>;
 
     #[salsa::invoke(crate::adt::EnumData::enum_data_query)]
-    fn enum_data(&self, e: Enum) -> Arc<EnumData>;
+    fn enum_data(&self, def_id: DefId) -> Arc<EnumData>;
 
     #[salsa::invoke(crate::adt::EnumVariantData::enum_variant_data_query)]
-    fn enum_variant_data(&self, var: EnumVariant) -> Arc<EnumVariantData>;
+    fn enum_variant_data(&self, def_id: DefId) -> Arc<EnumVariantData>;
 
     #[salsa::invoke(crate::ty::infer)]
-    fn infer(&self, func: Function) -> Arc<InferenceResult>;
+    fn infer(&self, def_id: DefId) -> Arc<InferenceResult>;
 
     #[salsa::invoke(crate::ty::type_for_def)]
-    fn type_for_def(&self, def: TypableDef) -> Ty;
+    fn type_for_def(&self, def_id: DefId) -> Ty;
 
     #[salsa::invoke(crate::ty::type_for_field)]
-    fn type_for_field(&self, def: VariantDef, field: Name) -> Option<Ty>;
+    fn type_for_field(&self, def_id: DefId, field: Name) -> Option<Ty>;
 
     #[salsa::invoke(query_definitions::file_items)]
     fn file_items(&self, file_id: HirFileId) -> Arc<SourceFileItems>;
@@ -57,35 +56,51 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> {
     fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>;
 
     #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)]
-    fn lower_module(&self, module: Module) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
+    fn lower_module(
+        &self,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
+    ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>);
 
     #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)]
-    fn lower_module_module(&self, module: Module) -> Arc<LoweredModule>;
+    fn lower_module_module(
+        &self,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
+    ) -> Arc<LoweredModule>;
 
     #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)]
-    fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>;
+    fn lower_module_source_map(
+        &self,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
+    ) -> Arc<ImportSourceMap>;
 
     #[salsa::invoke(query_definitions::item_map)]
-    fn item_map(&self, crate_id: CrateId) -> Arc<ItemMap>;
+    fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>;
 
     #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)]
-    fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>;
+    fn module_tree(&self, source_root_id: SourceRootId) -> Arc<ModuleTree>;
 
     #[salsa::invoke(crate::impl_block::impls_in_module)]
-    fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
+    fn impls_in_module(
+        &self,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
+    ) -> Arc<ModuleImplBlocks>;
 
     #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
     fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
 
     #[salsa::invoke(crate::expr::body_hir)]
-    fn body_hir(&self, func: Function) -> Arc<crate::expr::Body>;
+    fn body_hir(&self, def_id: DefId) -> Arc<crate::expr::Body>;
 
     #[salsa::invoke(crate::expr::body_syntax_mapping)]
-    fn body_syntax_mapping(&self, func: Function) -> Arc<crate::expr::BodySyntaxMapping>;
+    fn body_syntax_mapping(&self, def_id: DefId) -> Arc<crate::expr::BodySyntaxMapping>;
 
     #[salsa::invoke(crate::generics::GenericParams::generic_params_query)]
-    fn generic_params(&self, def: GenericDef) -> Arc<GenericParams>;
+    fn generic_params(&self, def_id: DefId) -> Arc<GenericParams>;
 
     #[salsa::invoke(crate::FnSignature::fn_signature_query)]
-    fn fn_signature(&self, func: Function) -> Arc<FnSignature>;
+    fn fn_signature(&self, def_id: DefId) -> Arc<FnSignature>;
 }
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 29469af2cf..1a38216922 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -9,11 +9,7 @@ use ra_syntax::{
     ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}
 };
 
-use crate::{
-    Path, Name, HirDatabase, Function,
-    name::AsName,
-    type_ref::{Mutability, TypeRef},
-};
+use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName};
 use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy};
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -439,8 +435,8 @@ impl Pat {
 
 // Queries
 
-pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc<Body> {
-    Arc::clone(&body_syntax_mapping(db, func).body)
+pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc<Body> {
+    Arc::clone(&body_syntax_mapping(db, def_id).body)
 }
 
 struct ExprCollector {
@@ -959,8 +955,14 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping {
     collector.into_body_syntax_mapping(params, body)
 }
 
-pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, func: Function) -> Arc<BodySyntaxMapping> {
-    let (_, fn_def) = func.source(db);
-    let body_syntax_mapping = collect_fn_body_syntax(&fn_def);
+pub(crate) fn body_syntax_mapping(db: &impl HirDatabase, def_id: DefId) -> Arc<BodySyntaxMapping> {
+    let def = def_id.resolve(db);
+
+    let body_syntax_mapping = match def {
+        Def::Function(f) => collect_fn_body_syntax(&f.source(db).1),
+        // TODO: consts, etc.
+        _ => panic!("Trying to get body for item type without body"),
+    };
+
     Arc::new(body_syntax_mapping)
 }
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index 64c20a4622..d8248ad491 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -5,9 +5,9 @@
 
 use std::sync::Arc;
 
-use ra_syntax::ast::{self, NameOwner, TypeParamsOwner};
+use ra_syntax::ast::{TypeParamList, AstNode, NameOwner};
 
-use crate::{db::HirDatabase, Name, AsName, Function, Struct, Enum, Trait, Type};
+use crate::{db::HirDatabase, DefId, Name, AsName};
 
 /// Data about a generic parameter (to a function, struct, impl, ...).
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -22,53 +22,26 @@ pub struct GenericParams {
     pub(crate) params: Vec<GenericParam>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-pub enum GenericDef {
-    Function(Function),
-    Struct(Struct),
-    Enum(Enum),
-    Trait(Trait),
-    Type(Type),
-}
-impl_froms!(GenericDef: Function, Struct, Enum, Trait, Type);
-
 impl GenericParams {
-    pub(crate) fn generic_params_query(
-        db: &impl HirDatabase,
-        def: GenericDef,
-    ) -> Arc<GenericParams> {
+    pub(crate) fn generic_params_query(db: &impl HirDatabase, def_id: DefId) -> Arc<GenericParams> {
+        let (_file_id, node) = def_id.source(db);
         let mut generics = GenericParams::default();
-        match def {
-            GenericDef::Function(it) => generics.fill(&*it.source(db).1),
-            GenericDef::Struct(it) => generics.fill(&*it.source(db).1),
-            GenericDef::Enum(it) => generics.fill(&*it.source(db).1),
-            GenericDef::Trait(it) => generics.fill(&*it.source(db).1),
-            GenericDef::Type(it) => generics.fill(&*it.source(db).1),
+        if let Some(type_param_list) = node.children().find_map(TypeParamList::cast) {
+            for (idx, type_param) in type_param_list.type_params().enumerate() {
+                let name = type_param
+                    .name()
+                    .map(AsName::as_name)
+                    .unwrap_or_else(Name::missing);
+                let param = GenericParam {
+                    idx: idx as u32,
+                    name,
+                };
+                generics.params.push(param);
+            }
         }
-
         Arc::new(generics)
     }
 
-    fn fill(&mut self, node: &impl TypeParamsOwner) {
-        if let Some(params) = node.type_param_list() {
-            self.fill_params(params)
-        }
-    }
-
-    fn fill_params(&mut self, params: &ast::TypeParamList) {
-        for (idx, type_param) in params.type_params().enumerate() {
-            let name = type_param
-                .name()
-                .map(AsName::as_name)
-                .unwrap_or_else(Name::missing);
-            let param = GenericParam {
-                idx: idx as u32,
-                name,
-            };
-            self.params.push(param);
-        }
-    }
-
     pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> {
         self.params.iter().find(|p| &p.name == name)
     }
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index b125a15184..43f0e81f9f 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -1,41 +1,22 @@
-use std::{
-    marker::PhantomData,
-    hash::{Hash, Hasher},
-};
-
-use ra_db::{LocationIntener, FileId};
+use ra_db::{SourceRootId, LocationIntener, FileId};
 use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast};
-use ra_arena::{Arena, RawId, ArenaId, impl_arena_id};
+use ra_arena::{Arena, RawId, impl_arena_id};
 
 use crate::{
-    HirDatabase,
-    Module,
+    HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate,
+    Module, Trait, Type, Static, Const,
+    module_tree::ModuleId,
 };
 
 #[derive(Debug, Default)]
 pub struct HirInterner {
+    defs: LocationIntener<DefLoc, DefId>,
     macros: LocationIntener<MacroCallLoc, MacroCallId>,
-    fns: LocationIntener<ItemLoc<ast::FnDef>, FunctionId>,
-    structs: LocationIntener<ItemLoc<ast::StructDef>, StructId>,
-    enums: LocationIntener<ItemLoc<ast::EnumDef>, EnumId>,
-    enum_variants: LocationIntener<ItemLoc<ast::EnumVariant>, EnumVariantId>,
-    consts: LocationIntener<ItemLoc<ast::ConstDef>, ConstId>,
-    statics: LocationIntener<ItemLoc<ast::StaticDef>, StaticId>,
-    traits: LocationIntener<ItemLoc<ast::TraitDef>, TraitId>,
-    types: LocationIntener<ItemLoc<ast::TypeDef>, TypeId>,
 }
 
 impl HirInterner {
     pub fn len(&self) -> usize {
-        self.macros.len()
-            + self.fns.len()
-            + self.structs.len()
-            + self.enums.len()
-            + self.enum_variants.len()
-            + self.consts.len()
-            + self.statics.len()
-            + self.traits.len()
-            + self.types.len()
+        self.defs.len() + self.macros.len()
     }
 }
 
@@ -129,9 +110,10 @@ impl From<MacroCallId> for HirFileId {
 pub struct MacroCallId(RawId);
 impl_arena_id!(MacroCallId);
 
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct MacroCallLoc {
-    pub(crate) module: Module,
+    pub(crate) source_root_id: SourceRootId,
+    pub(crate) module_id: ModuleId,
     pub(crate) source_item_id: SourceItemId,
 }
 
@@ -148,161 +130,117 @@ impl MacroCallLoc {
     }
 }
 
-#[derive(Debug)]
-pub struct ItemLoc<N: AstNode> {
-    pub(crate) module: Module,
-    raw: SourceItemId,
-    _ty: PhantomData<N>,
+/// Def's are a core concept of hir. A `Def` is an Item (function, module, etc)
+/// in a specific module.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct DefId(RawId);
+impl_arena_id!(DefId);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct DefLoc {
+    pub(crate) kind: DefKind,
+    pub(crate) source_root_id: SourceRootId,
+    pub(crate) module_id: ModuleId,
+    pub(crate) source_item_id: SourceItemId,
 }
 
-impl<N: AstNode> PartialEq for ItemLoc<N> {
-    fn eq(&self, other: &Self) -> bool {
-        self.module == other.module && self.raw == other.raw
-    }
-}
-impl<N: AstNode> Eq for ItemLoc<N> {}
-impl<N: AstNode> Hash for ItemLoc<N> {
-    fn hash<H: Hasher>(&self, hasher: &mut H) {
-        self.module.hash(hasher);
-        self.raw.hash(hasher);
-    }
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub(crate) enum DefKind {
+    Module,
+    Function,
+    Struct,
+    Enum,
+    EnumVariant,
+    Const,
+    Static,
+    Trait,
+    Type,
+    Item,
+
+    /// The constructor of a struct. E.g. if we have `struct Foo(usize)`, the
+    /// name `Foo` needs to resolve to different types depending on whether we
+    /// are in the types or values namespace: As a type, `Foo` of course refers
+    /// to the struct `Foo`; as a value, `Foo` is a callable type with signature
+    /// `(usize) -> Foo`. The cleanest approach to handle this seems to be to
+    /// have different defs in the two namespaces.
+    ///
+    /// rustc does the same; note that it even creates a struct constructor if
+    /// the struct isn't a tuple struct (see `CtorKind::Fictive` in rustc).
+    StructCtor,
 }
 
-impl<N: AstNode> Clone for ItemLoc<N> {
-    fn clone(&self) -> ItemLoc<N> {
-        ItemLoc {
-            module: self.module,
-            raw: self.raw,
-            _ty: PhantomData,
-        }
+impl DefId {
+    pub(crate) fn loc(self, db: &impl AsRef<HirInterner>) -> DefLoc {
+        db.as_ref().defs.id2loc(self)
     }
-}
 
-#[derive(Clone, Copy)]
-pub(crate) struct LocationCtx<DB> {
-    db: DB,
-    module: Module,
-    file_id: HirFileId,
-}
+    pub fn resolve(self, db: &impl HirDatabase) -> Def {
+        let loc = self.loc(db);
+        match loc.kind {
+            DefKind::Module => {
+                let module = Module::from_module_id(db, loc.source_root_id, loc.module_id);
+                Def::Module(module)
+            }
+            DefKind::Function => {
+                let function = Function::new(self);
+                Def::Function(function)
+            }
+            DefKind::Struct => {
+                let struct_def = Struct::new(self);
+                Def::Struct(struct_def)
+            }
+            DefKind::Enum => Def::Enum(Enum::new(self)),
+            DefKind::EnumVariant => Def::EnumVariant(EnumVariant::new(self)),
+            DefKind::Const => {
+                let def = Const::new(self);
+                Def::Const(def)
+            }
+            DefKind::Static => {
+                let def = Static::new(self);
+                Def::Static(def)
+            }
+            DefKind::Trait => {
+                let def = Trait::new(self);
+                Def::Trait(def)
+            }
+            DefKind::Type => {
+                let def = Type::new(self);
+                Def::Type(def)
+            }
 
-impl<'a, DB: HirDatabase> LocationCtx<&'a DB> {
-    pub(crate) fn new(db: &'a DB, module: Module, file_id: HirFileId) -> LocationCtx<&'a DB> {
-        LocationCtx {
-            db,
-            module,
-            file_id,
+            DefKind::StructCtor => Def::Item,
+            DefKind::Item => Def::Item,
         }
     }
-    pub(crate) fn to_def<N, DEF>(self, ast: &N) -> DEF
-    where
-        N: AstNode,
-        DEF: AstItemDef<N>,
-    {
-        DEF::from_ast(self, ast)
-    }
-}
-
-pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>;
-    fn from_ast(ctx: LocationCtx<&impl HirDatabase>, ast: &N) -> Self {
-        let items = ctx.db.file_items(ctx.file_id);
-        let raw = SourceItemId {
-            file_id: ctx.file_id,
-            item_id: Some(items.id_of(ctx.file_id, ast.syntax())),
-        };
-        let loc = ItemLoc {
-            module: ctx.module,
-            raw,
-            _ty: PhantomData,
-        };
-
-        Self::interner(ctx.db.as_ref()).loc2id(&loc)
-    }
-    fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<N>) {
-        let int = Self::interner(db.as_ref());
-        let loc = int.id2loc(self);
-        let syntax = db.file_item(loc.raw);
-        let ast = N::cast(&syntax)
-            .unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw))
-            .to_owned();
-        (loc.raw.file_id, ast)
-    }
-    fn module(self, db: &impl HirDatabase) -> Module {
-        let int = Self::interner(db.as_ref());
-        let loc = int.id2loc(self);
-        loc.module
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct FunctionId(RawId);
-impl_arena_id!(FunctionId);
-impl AstItemDef<ast::FnDef> for FunctionId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::FnDef>, Self> {
-        &interner.fns
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct StructId(RawId);
-impl_arena_id!(StructId);
-impl AstItemDef<ast::StructDef> for StructId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::StructDef>, Self> {
-        &interner.structs
-    }
-}
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct EnumId(RawId);
-impl_arena_id!(EnumId);
-impl AstItemDef<ast::EnumDef> for EnumId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::EnumDef>, Self> {
-        &interner.enums
+    pub(crate) fn source(self, db: &impl HirDatabase) -> (HirFileId, TreeArc<SyntaxNode>) {
+        let loc = self.loc(db);
+        let syntax = db.file_item(loc.source_item_id);
+        (loc.source_item_id.file_id, syntax)
     }
-}
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct EnumVariantId(RawId);
-impl_arena_id!(EnumVariantId);
-impl AstItemDef<ast::EnumVariant> for EnumVariantId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::EnumVariant>, Self> {
-        &interner.enum_variants
+    /// For a module, returns that module; for any other def, returns the containing module.
+    pub fn module(self, db: &impl HirDatabase) -> Module {
+        let loc = self.loc(db);
+        Module::from_module_id(db, loc.source_root_id, loc.module_id)
     }
-}
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct ConstId(RawId);
-impl_arena_id!(ConstId);
-impl AstItemDef<ast::ConstDef> for ConstId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::ConstDef>, Self> {
-        &interner.consts
+    /// Returns the containing crate.
+    pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
+        self.module(db).krate(db)
     }
-}
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct StaticId(RawId);
-impl_arena_id!(StaticId);
-impl AstItemDef<ast::StaticDef> for StaticId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::StaticDef>, Self> {
-        &interner.statics
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct TraitId(RawId);
-impl_arena_id!(TraitId);
-impl AstItemDef<ast::TraitDef> for TraitId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::TraitDef>, Self> {
-        &interner.traits
+    /// Returns the containing impl block, if this is an impl item.
+    pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> {
+        let loc = self.loc(db);
+        let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id);
+        ImplBlock::containing(module_impls, self)
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct TypeId(RawId);
-impl_arena_id!(TypeId);
-impl AstItemDef<ast::TypeDef> for TypeId {
-    fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<ast::TypeDef>, Self> {
-        &interner.types
+impl DefLoc {
+    pub(crate) fn id(&self, db: &impl AsRef<HirInterner>) -> DefId {
+        db.as_ref().defs.loc2id(&self)
     }
 }
 
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 222e473491..551d0d149d 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -3,13 +3,14 @@ use rustc_hash::FxHashMap;
 
 use ra_arena::{Arena, RawId, impl_arena_id};
 use ra_syntax::ast::{self, AstNode};
+use ra_db::{SourceRootId};
 
 use crate::{
-    Const, Type,
-    Function, HirFileId,
+    DefId, DefLoc, DefKind, SourceItemId, SourceFileItems,
+    Function, HirInterner,
     db::HirDatabase,
     type_ref::TypeRef,
-    ids::LocationCtx,
+    module_tree::ModuleId,
 };
 
 use crate::code_model_api::{Module, ModuleSource};
@@ -23,9 +24,9 @@ pub struct ImplBlock {
 impl ImplBlock {
     pub(crate) fn containing(
         module_impl_blocks: Arc<ModuleImplBlocks>,
-        item: ImplItem,
+        def_id: DefId,
     ) -> Option<ImplBlock> {
-        let impl_id = *module_impl_blocks.impls_by_def.get(&item)?;
+        let impl_id = *module_impl_blocks.impls_by_def.get(&def_id)?;
         Some(ImplBlock {
             module_impl_blocks,
             impl_id,
@@ -65,25 +66,39 @@ pub struct ImplData {
 
 impl ImplData {
     pub(crate) fn from_ast(
-        db: &impl HirDatabase,
-        file_id: HirFileId,
-        module: Module,
+        db: &impl AsRef<HirInterner>,
+        file_items: &SourceFileItems,
+        module: &Module,
         node: &ast::ImplBlock,
     ) -> Self {
         let target_trait = node.target_trait().map(TypeRef::from_ast);
         let target_type = TypeRef::from_ast_opt(node.target_type());
-        let ctx = LocationCtx::new(db, module, file_id);
+        let module_loc = module.def_id.loc(db);
         let items = if let Some(item_list) = node.item_list() {
             item_list
                 .impl_items()
-                .map(|item_node| match item_node.kind() {
-                    ast::ImplItemKind::FnDef(it) => {
-                        ImplItem::Method(Function { id: ctx.to_def(it) })
+                .map(|item_node| {
+                    let kind = match item_node.kind() {
+                        ast::ImplItemKind::FnDef(..) => DefKind::Function,
+                        ast::ImplItemKind::ConstDef(..) => DefKind::Item,
+                        ast::ImplItemKind::TypeDef(..) => DefKind::Item,
+                    };
+                    let item_id = file_items.id_of_unchecked(item_node.syntax());
+                    let source_item_id = SourceItemId {
+                        file_id: module_loc.source_item_id.file_id,
+                        item_id: Some(item_id),
+                    };
+                    let def_loc = DefLoc {
+                        kind,
+                        source_item_id,
+                        ..module_loc
+                    };
+                    let def_id = def_loc.id(db);
+                    match item_node.kind() {
+                        ast::ImplItemKind::FnDef(..) => ImplItem::Method(Function::new(def_id)),
+                        ast::ImplItemKind::ConstDef(..) => ImplItem::Const(def_id),
+                        ast::ImplItemKind::TypeDef(..) => ImplItem::Type(def_id),
                     }
-                    ast::ImplItemKind::ConstDef(it) => {
-                        ImplItem::Const(Const { id: ctx.to_def(it) })
-                    }
-                    ast::ImplItemKind::TypeDef(it) => ImplItem::Type(Type { id: ctx.to_def(it) }),
                 })
                 .collect()
         } else {
@@ -109,19 +124,22 @@ impl ImplData {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-//TODO: rename to ImplDef?
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ImplItem {
     Method(Function),
-    Const(Const),
-    Type(Type),
+    // these don't have their own types yet
+    Const(DefId),
+    Type(DefId),
     // Existential
 }
-impl_froms!(ImplItem: Const, Type);
 
-impl From<Function> for ImplItem {
-    fn from(func: Function) -> ImplItem {
-        ImplItem::Method(func)
+impl ImplItem {
+    pub fn def_id(&self) -> DefId {
+        match self {
+            ImplItem::Method(f) => f.def_id(),
+            ImplItem::Const(def_id) => *def_id,
+            ImplItem::Type(def_id) => *def_id,
+        }
     }
 }
 
@@ -137,7 +155,7 @@ impl_arena_id!(ImplId);
 #[derive(Debug, PartialEq, Eq)]
 pub struct ModuleImplBlocks {
     pub(crate) impls: Arena<ImplId, ImplData>,
-    impls_by_def: FxHashMap<ImplItem, ImplId>,
+    impls_by_def: FxHashMap<DefId, ImplId>,
 }
 
 impl ModuleImplBlocks {
@@ -150,7 +168,6 @@ impl ModuleImplBlocks {
 
     fn collect(&mut self, db: &impl HirDatabase, module: Module) {
         let (file_id, module_source) = module.definition_source(db);
-        let file_id: HirFileId = file_id.into();
         let node = match &module_source {
             ModuleSource::SourceFile(node) => node.syntax(),
             ModuleSource::Module(node) => node
@@ -159,18 +176,25 @@ impl ModuleImplBlocks {
                 .syntax(),
         };
 
+        let source_file_items = db.file_items(file_id.into());
+
         for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) {
-            let impl_block = ImplData::from_ast(db, file_id, module, impl_block_ast);
+            let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast);
             let id = self.impls.alloc(impl_block);
-            for &impl_item in &self.impls[id].items {
-                self.impls_by_def.insert(impl_item, id);
+            for impl_item in &self.impls[id].items {
+                self.impls_by_def.insert(impl_item.def_id(), id);
             }
         }
     }
 }
 
-pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
+pub(crate) fn impls_in_module(
+    db: &impl HirDatabase,
+    source_root_id: SourceRootId,
+    module_id: ModuleId,
+) -> Arc<ModuleImplBlocks> {
     let mut result = ModuleImplBlocks::new();
+    let module = Module::from_module_id(db, source_root_id, module_id);
     result.collect(db, module);
     Arc::new(result)
 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 596f9c38c3..87b5a8b8a0 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -5,18 +5,6 @@
 //! 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.
 
-macro_rules! impl_froms {
-    ($e:ident: $($v:ident), *) => {
-        $(
-            impl From<$v> for $e {
-                fn from(it: $v) -> $e {
-                    $e::$v(it)
-                }
-            }
-        )*
-    }
-}
-
 pub mod db;
 #[cfg(test)]
 mod mock;
@@ -46,26 +34,25 @@ mod marks;
 use crate::{
     db::HirDatabase,
     name::{AsName, KnownName},
-    ids::{SourceItemId, SourceFileItems},
+    ids::{DefKind, SourceItemId, SourceFileItems},
 };
 
 pub use self::{
     path::{Path, PathKind},
     name::Name,
-    ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
+    ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc, HirInterner},
     macros::{MacroDef, MacroInput, MacroExpansion},
     nameres::{ItemMap, PerNs, Namespace, Resolution},
     ty::Ty,
     impl_block::{ImplBlock, ImplItem},
     code_model_impl::function::{FnScopes, ScopesWithSyntaxMapping},
-    docs::{Docs, Documentation},
-    adt::AdtDef,
+    docs::{Docs, Documentation}
 };
 
 pub use self::code_model_api::{
     Crate, CrateDependency,
     Def,
-    Module, ModuleDef, ModuleSource, Problem,
+    Module, ModuleSource, Problem,
     Struct, Enum, EnumVariant,
     Function, FnSignature, ScopeEntryWithSyntax,
     StructField,
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 361366f6a1..4145c80487 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -35,6 +35,10 @@ impl MockDatabase {
         let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text);
         db.query_mut(ra_db::SourceRootQuery)
             .set(WORKSPACE, Arc::new(source_root.clone()));
+
+        let mut crate_graph = CrateGraph::default();
+        crate_graph.add_crate_root(file_id);
+        db.set_crate_graph(crate_graph);
         (db, source_root, file_id)
     }
 
@@ -93,8 +97,6 @@ impl MockDatabase {
         text: &str,
     ) -> FileId {
         assert!(path.starts_with('/'));
-        let is_crate_root = path == "/lib.rs" || path == "/main.rs";
-
         let path = RelativePathBuf::from_path(&path[1..]).unwrap();
         let file_id = FileId(self.file_counter);
         self.file_counter += 1;
@@ -105,12 +107,6 @@ impl MockDatabase {
         self.query_mut(ra_db::FileSourceRootQuery)
             .set(file_id, source_root_id);
         source_root.files.insert(path, file_id);
-
-        if is_crate_root {
-            let mut crate_graph = CrateGraph::default();
-            crate_graph.add_crate_root(file_id);
-            self.set_crate_graph(crate_graph);
-        }
         file_id
     }
 
@@ -206,7 +202,6 @@ salsa::database_storage! {
             fn file_relative_path() for ra_db::FileRelativePathQuery;
             fn file_source_root() for ra_db::FileSourceRootQuery;
             fn source_root() for ra_db::SourceRootQuery;
-            fn source_root_crates() for ra_db::SourceRootCratesQuery;
             fn local_roots() for ra_db::LocalRootsQuery;
             fn library_roots() for ra_db::LibraryRootsQuery;
             fn crate_graph() for ra_db::CrateGraphQuery;
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs
index c00834c4c1..b201bf69bf 100644
--- a/crates/ra_hir/src/module_tree.rs
+++ b/crates/ra_hir/src/module_tree.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
 use rustc_hash::{FxHashMap, FxHashSet};
 use arrayvec::ArrayVec;
 use relative_path::RelativePathBuf;
-use ra_db::{FileId, SourceRoot, CrateId};
+use ra_db::{FileId, SourceRootId, SourceRoot};
 use ra_syntax::{
     SyntaxNode, TreeArc,
     algo::generate,
@@ -126,10 +126,13 @@ struct LinkData {
 }
 
 impl ModuleTree {
-    pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> {
+    pub(crate) fn module_tree_query(
+        db: &impl HirDatabase,
+        source_root: SourceRootId,
+    ) -> Arc<ModuleTree> {
         db.check_canceled();
         let mut res = ModuleTree::default();
-        res.init_crate(db, crate_id);
+        res.init(db, source_root);
         Arc::new(res)
     }
 
@@ -142,21 +145,24 @@ impl ModuleTree {
         Some(res)
     }
 
-    fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) {
-        let crate_graph = db.crate_graph();
-        let file_id = crate_graph.crate_root(crate_id);
-        let source_root_id = db.file_source_root(file_id);
-
+    fn init(&mut self, db: &impl HirDatabase, source_root: SourceRootId) {
         let mut roots = FxHashMap::default();
         let mut visited = FxHashSet::default();
 
-        let source_root = db.source_root(source_root_id);
-        let source = SourceItemId {
-            file_id: file_id.into(),
-            item_id: None,
-        };
-        let module_id = self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
-        roots.insert(file_id, module_id);
+        let source_root = db.source_root(source_root);
+        for &file_id in source_root.files.values() {
+            let source = SourceItemId {
+                file_id: file_id.into(),
+                item_id: None,
+            };
+            if visited.contains(&source) {
+                continue; // TODO: use explicit crate_roots here
+            }
+            assert!(!roots.contains_key(&file_id));
+            let module_id =
+                self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source);
+            roots.insert(file_id, module_id);
+        }
     }
 
     fn init_subtree(
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index a3bc989580..1d163edf7d 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -16,19 +16,19 @@
 //! structure itself is modified.
 pub(crate) mod lower;
 
+use crate::nameres::lower::*;
+
 use std::sync::Arc;
 
-use ra_db::CrateId;
 use rustc_hash::{FxHashMap, FxHashSet};
+use ra_db::SourceRootId;
 
 use crate::{
-    Module, ModuleDef,
+    DefId, DefLoc, DefKind,
     Path, PathKind,
     HirDatabase, Crate,
     Name,
     module_tree::{ModuleId, ModuleTree},
-//FIXME: deglobify
-    nameres::lower::*,
 };
 
 /// `ItemMap` is the result of name resolution. It contains, for each
@@ -58,7 +58,7 @@ impl ModuleScope {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Resolution {
     /// None for unresolved
-    pub def_id: PerNs<ModuleDef>,
+    pub def_id: PerNs<DefId>,
     /// ident by which this is imported into local scope.
     pub import: Option<ImportId>,
 }
@@ -152,7 +152,7 @@ impl<T> PerNs<T> {
 pub(crate) struct Resolver<'a, DB> {
     db: &'a DB,
     input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
-    krate: CrateId,
+    source_root: SourceRootId,
     module_tree: Arc<ModuleTree>,
     processed_imports: FxHashSet<(ModuleId, ImportId)>,
     result: ItemMap,
@@ -165,13 +165,13 @@ where
     pub(crate) fn new(
         db: &'a DB,
         input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
-        krate: CrateId,
+        source_root: SourceRootId,
+        module_tree: Arc<ModuleTree>,
     ) -> Resolver<'a, DB> {
-        let module_tree = db.module_tree(krate);
         Resolver {
             db,
             input,
-            krate,
+            source_root,
             module_tree,
             processed_imports: FxHashSet::default(),
             result: ItemMap::default(),
@@ -210,7 +210,7 @@ where
                 let krate = Crate::new(crate_id);
                 for dep in krate.dependencies(self.db) {
                     if let Some(module) = dep.krate.root_module(self.db) {
-                        let def_id = module.into();
+                        let def_id = module.def_id;
                         self.add_module_item(
                             &mut module_items,
                             dep.name.clone(),
@@ -244,22 +244,20 @@ where
 
         // Populate modules
         for (name, module_id) in module_id.children(&self.module_tree) {
-            let module = Module {
+            let def_loc = DefLoc {
+                kind: DefKind::Module,
+                source_root_id: self.source_root,
                 module_id,
-                krate: self.krate,
+                source_item_id: module_id.source(&self.module_tree),
             };
-            self.add_module_item(&mut module_items, name, PerNs::types(module.into()));
+            let def_id = def_loc.id(self.db);
+            self.add_module_item(&mut module_items, name, PerNs::types(def_id));
         }
 
         self.result.per_module.insert(module_id, module_items);
     }
 
-    fn add_module_item(
-        &self,
-        module_items: &mut ModuleScope,
-        name: Name,
-        def_id: PerNs<ModuleDef>,
-    ) {
+    fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) {
         let resolution = Resolution {
             def_id,
             import: None,
@@ -331,11 +329,17 @@ where
                     );
                     return false;
                 };
-                curr = match type_def_id {
-                    ModuleDef::Module(module) => {
-                        if module.krate == self.krate {
-                            module.module_id
+                curr = match type_def_id.loc(self.db) {
+                    DefLoc {
+                        kind: DefKind::Module,
+                        module_id: target_module_id,
+                        source_root_id,
+                        ..
+                    } => {
+                        if source_root_id == self.source_root {
+                            target_module_id
                         } else {
+                            let module = crate::code_model_api::Module::new(type_def_id);
                             let path = Path {
                                 segments: import.path.segments[i + 1..].iter().cloned().collect(),
                                 kind: PathKind::Crate,
@@ -355,7 +359,7 @@ where
                                     "resolved import {:?} ({:?}) cross-source root to {:?}",
                                     last_segment.name,
                                     import,
-                                    def_id,
+                                    def_id.map(|did| did.loc(self.db))
                                 );
                                 return true;
                             } else {
@@ -368,7 +372,7 @@ where
                         log::debug!(
                             "path segment {:?} resolved to non-module {:?}, but is not last",
                             segment.name,
-                            type_def_id,
+                            type_def_id.loc(self.db)
                         );
                         return true; // this resolved to a non-module, so the path won't ever resolve
                     }
@@ -378,7 +382,7 @@ where
                     "resolved import {:?} ({:?}) within source root to {:?}",
                     segment.name,
                     import,
-                    def_id,
+                    def_id.map(|did| did.loc(self.db))
                 );
                 self.update(module_id, |items| {
                     let res = Resolution {
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs
index b4fe99ea70..4eea6ff1de 100644
--- a/crates/ra_hir/src/nameres/lower.rs
+++ b/crates/ra_hir/src/nameres/lower.rs
@@ -1,17 +1,17 @@
 use std::sync::Arc;
 
 use ra_syntax::{
-    AstNode, SourceFile, TreeArc, AstPtr,
+    SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr,
     ast::{self, ModuleItemOwner, NameOwner},
 };
+use ra_db::SourceRootId;
 use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
 use rustc_hash::FxHashMap;
 
 use crate::{
-    SourceItemId, Path, ModuleSource, HirDatabase, Name,
-    HirFileId, MacroCallLoc, AsName, PerNs, Function,
-    ModuleDef, Module, Struct, Enum, Const, Static, Trait, Type,
-    ids::LocationCtx,
+    SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems,
+    HirFileId, MacroCallLoc, AsName, PerNs, DefId, DefKind, DefLoc,
+    module_tree::ModuleId
 };
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -32,7 +32,7 @@ pub(super) struct ImportData {
 /// can avoid redoing name resolution.
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct LoweredModule {
-    pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>,
+    pub(crate) declarations: FxHashMap<Name, PerNs<DefId>>,
     pub(super) imports: Arena<ImportId, ImportData>,
 }
 
@@ -59,31 +59,37 @@ impl ImportSourceMap {
 impl LoweredModule {
     pub(crate) fn lower_module_module_query(
         db: &impl HirDatabase,
-        module: Module,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
     ) -> Arc<LoweredModule> {
-        db.lower_module(module).0
+        db.lower_module(source_root_id, module_id).0
     }
 
     pub(crate) fn lower_module_source_map_query(
         db: &impl HirDatabase,
-        module: Module,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
     ) -> Arc<ImportSourceMap> {
-        db.lower_module(module).1
+        db.lower_module(source_root_id, module_id).1
     }
 
     pub(crate) fn lower_module_query(
         db: &impl HirDatabase,
-        module: Module,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
     ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) {
-        let (file_id, source) = module.definition_source(db);
-        let file_id: HirFileId = file_id.into();
+        let module_tree = db.module_tree(source_root_id);
+        let source = module_id.source(&module_tree);
+        let file_id = source.file_id;
+        let source = ModuleSource::from_source_item_id(db, source);
         let mut source_map = ImportSourceMap::default();
         let mut res = LoweredModule::default();
         match source {
             ModuleSource::SourceFile(it) => res.fill(
                 &mut source_map,
                 db,
-                module,
+                source_root_id,
+                module_id,
                 file_id,
                 &mut it.items_with_macros(),
             ),
@@ -92,7 +98,8 @@ impl LoweredModule {
                     res.fill(
                         &mut source_map,
                         db,
-                        module,
+                        source_root_id,
+                        module_id,
                         file_id,
                         &mut item_list.items_with_macros(),
                     )
@@ -106,7 +113,8 @@ impl LoweredModule {
         &mut self,
         source_map: &mut ImportSourceMap,
         db: &impl HirDatabase,
-        module: Module,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
         file_id: HirFileId,
         items: &mut Iterator<Item = ast::ItemOrMacro>,
     ) {
@@ -115,12 +123,21 @@ impl LoweredModule {
         for item in items {
             match item {
                 ast::ItemOrMacro::Item(it) => {
-                    self.add_def_id(source_map, db, module, file_id, it);
+                    self.add_def_id(
+                        source_map,
+                        db,
+                        source_root_id,
+                        module_id,
+                        file_id,
+                        &file_items,
+                        it,
+                    );
                 }
                 ast::ItemOrMacro::Macro(macro_call) => {
                     let item_id = file_items.id_of_unchecked(macro_call.syntax());
                     let loc = MacroCallLoc {
-                        module,
+                        source_root_id,
+                        module_id,
                         source_item_id: SourceItemId {
                             file_id,
                             item_id: Some(item_id),
@@ -128,9 +145,18 @@ impl LoweredModule {
                     };
                     let id = loc.id(db);
                     let file_id = HirFileId::from(id);
+                    let file_items = db.file_items(file_id);
                     //FIXME: expand recursively
                     for item in db.hir_source_file(file_id).items() {
-                        self.add_def_id(source_map, db, module, file_id, item);
+                        self.add_def_id(
+                            source_map,
+                            db,
+                            source_root_id,
+                            module_id,
+                            file_id,
+                            &file_items,
+                            item,
+                        );
                     }
                 }
             }
@@ -141,74 +167,41 @@ impl LoweredModule {
         &mut self,
         source_map: &mut ImportSourceMap,
         db: &impl HirDatabase,
-        module: Module,
+        source_root_id: SourceRootId,
+        module_id: ModuleId,
         file_id: HirFileId,
+        file_items: &SourceFileItems,
         item: &ast::ModuleItem,
     ) {
-        let ctx = LocationCtx::new(db, module, file_id);
-        match item.kind() {
-            ast::ModuleItemKind::StructDef(it) => {
-                if let Some(name) = it.name() {
-                    let s = Struct { id: ctx.to_def(it) };
-                    let s: ModuleDef = s.into();
-                    self.declarations.insert(name.as_name(), PerNs::both(s, s));
-                }
-            }
-            ast::ModuleItemKind::EnumDef(it) => {
-                if let Some(name) = it.name() {
-                    let e = Enum { id: ctx.to_def(it) };
-                    let e: ModuleDef = e.into();
-                    self.declarations.insert(name.as_name(), PerNs::types(e));
-                }
-            }
-            ast::ModuleItemKind::FnDef(it) => {
-                if let Some(name) = it.name() {
-                    let func = Function { id: ctx.to_def(it) };
-                    self.declarations
-                        .insert(name.as_name(), PerNs::values(func.into()));
-                }
-            }
-            ast::ModuleItemKind::TraitDef(it) => {
-                if let Some(name) = it.name() {
-                    let t = Trait { id: ctx.to_def(it) };
-                    self.declarations
-                        .insert(name.as_name(), PerNs::types(t.into()));
-                }
-            }
-            ast::ModuleItemKind::TypeDef(it) => {
-                if let Some(name) = it.name() {
-                    let t = Type { id: ctx.to_def(it) };
-                    self.declarations
-                        .insert(name.as_name(), PerNs::types(t.into()));
-                }
-            }
+        let name = match item.kind() {
+            ast::ModuleItemKind::StructDef(it) => it.name(),
+            ast::ModuleItemKind::EnumDef(it) => it.name(),
+            ast::ModuleItemKind::FnDef(it) => it.name(),
+            ast::ModuleItemKind::TraitDef(it) => it.name(),
+            ast::ModuleItemKind::TypeDef(it) => it.name(),
             ast::ModuleItemKind::ImplBlock(_) => {
                 // impls don't define items
+                return;
             }
             ast::ModuleItemKind::UseItem(it) => {
                 self.add_use_item(source_map, it);
+                return;
             }
             ast::ModuleItemKind::ExternCrateItem(_) => {
                 // TODO
+                return;
             }
-            ast::ModuleItemKind::ConstDef(it) => {
-                if let Some(name) = it.name() {
-                    let c = Const { id: ctx.to_def(it) };
-                    self.declarations
-                        .insert(name.as_name(), PerNs::values(c.into()));
-                }
-            }
-            ast::ModuleItemKind::StaticDef(it) => {
-                if let Some(name) = it.name() {
-                    let s = Static { id: ctx.to_def(it) };
-                    self.declarations
-                        .insert(name.as_name(), PerNs::values(s.into()));
-                }
-            }
+            ast::ModuleItemKind::ConstDef(it) => it.name(),
+            ast::ModuleItemKind::StaticDef(it) => it.name(),
             ast::ModuleItemKind::Module(_) => {
                 // modules are handled separately direclty by nameres
+                return;
             }
         };
+        if let Some(name) = name {
+            let def_id = assign_def_id(db, source_root_id, module_id, file_id, file_items, item);
+            self.declarations.insert(name.as_name(), def_id);
+        }
     }
 
     fn add_use_item(&mut self, source_map: &mut ImportSourceMap, item: &ast::UseItem) {
@@ -223,3 +216,46 @@ impl LoweredModule {
         })
     }
 }
+
+fn assign_def_id(
+    db: &impl HirDatabase,
+    source_root_id: SourceRootId,
+    module_id: ModuleId,
+    file_id: HirFileId,
+    file_items: &SourceFileItems,
+    item: &ast::ModuleItem,
+) -> PerNs<DefId> {
+    // depending on the item kind, the location can define something in
+    // the values namespace, the types namespace, or both
+    let kind = DefKind::for_syntax_kind(item.syntax().kind());
+    let def_id = kind.map(|k| {
+        let item_id = file_items.id_of_unchecked(item.syntax());
+        let def_loc = DefLoc {
+            kind: k,
+            source_root_id,
+            module_id,
+            source_item_id: SourceItemId {
+                file_id,
+                item_id: Some(item_id),
+            },
+        };
+        def_loc.id(db)
+    });
+    def_id
+}
+
+impl DefKind {
+    fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
+        match kind {
+            SyntaxKind::FN_DEF => PerNs::values(DefKind::Function),
+            SyntaxKind::MODULE => PerNs::types(DefKind::Module),
+            SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor),
+            SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum),
+            SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait),
+            SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Type),
+            SyntaxKind::CONST_DEF => PerNs::values(DefKind::Const),
+            SyntaxKind::STATIC_DEF => PerNs::values(DefKind::Static),
+            _ => PerNs::none(),
+        }
+    }
+}
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs
index cf8c7e4354..0741538626 100644
--- a/crates/ra_hir/src/query_definitions.rs
+++ b/crates/ra_hir/src/query_definitions.rs
@@ -7,17 +7,17 @@ use rustc_hash::FxHashMap;
 use ra_syntax::{
     AstNode, SyntaxNode, TreeArc,
 };
-use ra_db::{CrateId};
+use ra_db::SourceRootId;
 
 use crate::{
-    SourceFileItems, SourceItemId, HirFileId,
-    Function, FnScopes, Module,
+    SourceFileItems, SourceItemId, DefId, HirFileId,
+    FnScopes,
     db::HirDatabase,
     nameres::{ItemMap, Resolver},
 };
 
-pub(super) fn fn_scopes(db: &impl HirDatabase, func: Function) -> Arc<FnScopes> {
-    let body = db.body_hir(func);
+pub(super) fn fn_scopes(db: &impl HirDatabase, def_id: DefId) -> Arc<FnScopes> {
+    let body = db.body_hir(def_id);
     let res = FnScopes::new(body);
     Arc::new(res)
 }
@@ -41,23 +41,15 @@ pub(super) fn file_item(
     }
 }
 
-pub(super) fn item_map(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ItemMap> {
+pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> {
     let start = Instant::now();
-    let module_tree = db.module_tree(crate_id);
+    let module_tree = db.module_tree(source_root);
     let input = module_tree
         .modules()
-        .map(|module_id| {
-            (
-                module_id,
-                db.lower_module_module(Module {
-                    krate: crate_id,
-                    module_id,
-                }),
-            )
-        })
+        .map(|id| (id, db.lower_module_module(source_root, id)))
         .collect::<FxHashMap<_, _>>();
 
-    let resolver = Resolver::new(db, &input, crate_id);
+    let resolver = Resolver::new(db, &input, source_root, module_tree);
     let res = resolver.resolve();
     let elapsed = start.elapsed();
     log::info!("item_map: {:?}", elapsed);
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index dbe040805e..bde0be37b6 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,9 +13,8 @@ use ra_syntax::{
 };
 
 use crate::{
-    HirDatabase, Function, SourceItemId, ModuleDef,
-    AsName, Module,
-    ids::LocationCtx,
+    HirDatabase, Function, SourceItemId,
+    DefKind, DefLoc, AsName, Module,
 };
 
 /// Locates the module by `FileId`. Picks topmost module in the file.
@@ -85,13 +84,9 @@ pub fn module_from_child_node(
 
 fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> {
     let source_root_id = db.file_source_root(source.file_id.as_original_file());
-    db.source_root_crates(source_root_id)
-        .iter()
-        .find_map(|&krate| {
-            let module_tree = db.module_tree(krate);
-            let module_id = module_tree.find_module_by_source(source)?;
-            Some(Module { krate, module_id })
-        })
+    let module_tree = db.module_tree(source_root_id);
+    let module_id = module_tree.find_module_by_source(source)?;
+    Some(Module::from_module_id(db, source_root_id, module_id))
 }
 
 pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> {
@@ -106,21 +101,30 @@ pub fn function_from_source(
     fn_def: &ast::FnDef,
 ) -> Option<Function> {
     let module = module_from_child_node(db, file_id, fn_def.syntax())?;
-    let res = function_from_module(db, module, fn_def);
+    let res = function_from_module(db, &module, fn_def);
     Some(res)
 }
 
 pub fn function_from_module(
     db: &impl HirDatabase,
-    module: Module,
+    module: &Module,
     fn_def: &ast::FnDef,
 ) -> Function {
-    let (file_id, _) = module.definition_source(db);
-    let file_id = file_id.into();
-    let ctx = LocationCtx::new(db, module, file_id);
-    Function {
-        id: ctx.to_def(fn_def),
-    }
+    let loc = module.def_id.loc(db);
+    let file_id = loc.source_item_id.file_id;
+    let file_items = db.file_items(file_id);
+    let item_id = file_items.id_of(file_id, fn_def.syntax());
+    let source_item_id = SourceItemId {
+        file_id,
+        item_id: Some(item_id),
+    };
+    let def_loc = DefLoc {
+        kind: DefKind::Function,
+        source_root_id: loc.source_root_id,
+        module_id: loc.module_id,
+        source_item_id,
+    };
+    Function::new(def_loc.id(db))
 }
 
 pub fn function_from_child_node(
@@ -137,18 +141,15 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te
         Some(it) => it,
         None => return Vec::new(),
     };
-    let items = db.lower_module_module(module);
+    let loc = module.def_id.loc(db);
+    let items = db.lower_module_module(loc.source_root_id, loc.module_id);
     let mut res = Vec::new();
 
     for macro_call_id in items
         .declarations
         .iter()
-        .filter_map(|(_, it)| it.clone().take_types())
-        .filter_map(|it| match it {
-            ModuleDef::Trait(it) => Some(it),
-            _ => None,
-        })
-        .filter_map(|it| it.source(db).0.as_macro_call_id())
+        .filter_map(|(_, it)| it.take_types())
+        .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id())
     {
         if let Some(exp) = db.expand_macro_invocation(macro_call_id) {
             let loc = macro_call_id.loc(db);
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index c7f77e7a39..e690ae1582 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -24,14 +24,15 @@ use std::ops::Index;
 use std::sync::Arc;
 use std::{fmt, mem};
 
+use log;
 use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError};
 use ra_arena::map::ArenaMap;
 use join_to_string::join;
 use rustc_hash::FxHashMap;
 
 use crate::{
-    Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
-    FnSignature, FnScopes, ModuleDef, AdtDef,
+    Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock,
+    FnSignature, FnScopes,
     db::HirDatabase,
     type_ref::{TypeRef, Mutability},
     name::KnownName,
@@ -183,7 +184,7 @@ pub enum Ty {
     /// Structures, enumerations and unions.
     Adt {
         /// The DefId of the struct/enum.
-        def_id: AdtDef,
+        def_id: DefId,
         /// The name, for displaying.
         name: Name,
         /// Substitutions for the generic parameters of the type.
@@ -380,16 +381,12 @@ impl Ty {
         }
 
         // Resolve in module (in type namespace)
-        let typable: TypableDef = match module
-            .resolve_path(db, path)
-            .take_types()
-            .and_then(|it| it.into())
-        {
+        let resolved = match module.resolve_path(db, path).take_types() {
+            Some(r) => r,
             None => return Ty::Unknown,
-            Some(it) => it,
         };
-        let ty = db.type_for_def(typable);
-        let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable);
+        let ty = db.type_for_def(resolved);
+        let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved);
         ty.apply_substs(substs)
     }
 
@@ -402,18 +399,20 @@ impl Ty {
         impl_block: Option<&ImplBlock>,
         outer_generics: &GenericParams,
         path: &Path,
-        resolved: TypableDef,
+        resolved: DefId,
     ) -> Substs {
         let mut substs = Vec::new();
+        let def = resolved.resolve(db);
         let last = path
             .segments
             .last()
             .expect("path should have at least one segment");
-        let (def_generics, segment) = match resolved {
-            TypableDef::Function(func) => (func.generic_params(db), last),
-            TypableDef::Struct(s) => (s.generic_params(db), last),
-            TypableDef::Enum(e) => (e.generic_params(db), last),
-            TypableDef::EnumVariant(var) => {
+        let (def_generics, segment) = match def {
+            Def::Struct(s) => (s.generic_params(db), last),
+            Def::Enum(e) => (e.generic_params(db), last),
+            Def::Function(f) => (f.generic_params(db), last),
+            Def::Trait(t) => (t.generic_params(db), last),
+            Def::EnumVariant(ev) => {
                 // the generic args for an enum variant may be either specified
                 // on the segment referring to the enum, or on the segment
                 // referring to the variant. So `Option::<T>::None` and
@@ -427,8 +426,9 @@ impl Ty {
                     // Option::None::<T>
                     last
                 };
-                (var.parent_enum(db).generic_params(db), segment)
+                (ev.parent_enum(db).generic_params(db), segment)
             }
+            _ => return Substs::empty(),
         };
         // substs_from_path
         if let Some(generic_args) = &segment.args_and_bindings {
@@ -639,7 +639,7 @@ fn make_substs(generics: &GenericParams) -> Substs {
 fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
     let generics = s.generic_params(db);
     Ty::Adt {
-        def_id: s.into(),
+        def_id: s.def_id(),
         name: s.name(db).unwrap_or_else(Name::missing),
         substs: make_substs(&generics),
     }
@@ -648,7 +648,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
 pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
     let generics = s.generic_params(db);
     Ty::Adt {
-        def_id: s.into(),
+        def_id: s.def_id(),
         name: s.name(db).unwrap_or_else(Name::missing),
         substs: make_substs(&generics),
     }
@@ -660,74 +660,66 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T
     type_for_enum(db, enum_parent)
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum TypableDef {
-    Function(Function),
-    Struct(Struct),
-    Enum(Enum),
-    EnumVariant(EnumVariant),
-}
-impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant);
-
-impl From<ModuleDef> for Option<TypableDef> {
-    fn from(def: ModuleDef) -> Option<TypableDef> {
-        let res = match def {
-            ModuleDef::Function(f) => f.into(),
-            ModuleDef::Struct(s) => s.into(),
-            ModuleDef::Enum(e) => e.into(),
-            ModuleDef::EnumVariant(v) => v.into(),
-            ModuleDef::Const(_)
-            | ModuleDef::Static(_)
-            | ModuleDef::Module(_)
-            | ModuleDef::Trait(_)
-            | ModuleDef::Type(_) => return None,
-        };
-        Some(res)
-    }
-}
-
-pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
+pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty {
+    let def = def_id.resolve(db);
     match def {
-        TypableDef::Function(f) => type_for_fn(db, f),
-        TypableDef::Struct(s) => type_for_struct(db, s),
-        TypableDef::Enum(e) => type_for_enum(db, e),
-        TypableDef::EnumVariant(v) => type_for_enum_variant(db, v),
+        Def::Module(..) => {
+            log::debug!("trying to get type for module {:?}", def_id);
+            Ty::Unknown
+        }
+        Def::Function(f) => type_for_fn(db, f),
+        Def::Struct(s) => type_for_struct(db, s),
+        Def::Enum(e) => type_for_enum(db, e),
+        Def::EnumVariant(ev) => type_for_enum_variant(db, ev),
+        _ => {
+            log::debug!(
+                "trying to get type for item of unknown type {:?} {:?}",
+                def_id,
+                def
+            );
+            Ty::Unknown
+        }
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum VariantDef {
-    Struct(Struct),
-    EnumVariant(EnumVariant),
-}
-impl_froms!(VariantDef: Struct, EnumVariant);
-
-pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> {
-    let (variant_data, generics, module) = match def {
-        VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)),
-        VariantDef::EnumVariant(var) => (
-            var.variant_data(db),
-            var.parent_enum(db).generic_params(db),
-            var.module(db),
+pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> {
+    let def = def_id.resolve(db);
+    let (variant_data, generics) = match def {
+        Def::Struct(s) => (s.variant_data(db), s.generic_params(db)),
+        Def::EnumVariant(ev) => (ev.variant_data(db), ev.parent_enum(db).generic_params(db)),
+        // TODO: unions
+        Def::Enum(_) => {
+            // this can happen in (invalid) code, but enums don't have fields themselves
+            return None;
+        }
+        _ => panic!(
+            "trying to get type for field {:?} in non-struct/variant {:?}",
+            field, def_id
         ),
     };
-    // We can't have an impl block ere, right?
-    // let impl_block = def_id.impl_block(db);
+    let module = def_id.module(db);
+    let impl_block = def_id.impl_block(db);
     let type_ref = variant_data.get_field_type_ref(&field)?;
-    Some(Ty::from_hir(db, &module, None, &generics, &type_ref))
+    Some(Ty::from_hir(
+        db,
+        &module,
+        impl_block.as_ref(),
+        &generics,
+        &type_ref,
+    ))
 }
 
 /// The result of type inference: A mapping from expressions and patterns to types.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct InferenceResult {
     /// For each method call expr, record the function it resolved to.
-    method_resolutions: FxHashMap<ExprId, Function>,
+    method_resolutions: FxHashMap<ExprId, DefId>,
     type_of_expr: ArenaMap<ExprId, Ty>,
     type_of_pat: ArenaMap<PatId, Ty>,
 }
 
 impl InferenceResult {
-    pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
+    pub fn method_resolution(&self, expr: ExprId) -> Option<DefId> {
         self.method_resolutions.get(&expr).map(|it| *it)
     }
 }
@@ -757,7 +749,7 @@ struct InferenceContext<'a, D: HirDatabase> {
     module: Module,
     impl_block: Option<ImplBlock>,
     var_unification_table: InPlaceUnificationTable<TypeVarId>,
-    method_resolutions: FxHashMap<ExprId, Function>,
+    method_resolutions: FxHashMap<ExprId, DefId>,
     type_of_expr: ArenaMap<ExprId, Ty>,
     type_of_pat: ArenaMap<PatId, Ty>,
     /// The return type of the function being inferred.
@@ -883,8 +875,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
         self.type_of_expr.insert(expr, ty);
     }
 
-    fn write_method_resolution(&mut self, expr: ExprId, func: Function) {
-        self.method_resolutions.insert(expr, func);
+    fn write_method_resolution(&mut self, expr: ExprId, def_id: DefId) {
+        self.method_resolutions.insert(expr, def_id);
     }
 
     fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
@@ -1071,30 +1063,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
         };
 
         // resolve in module
-        let typable: Option<TypableDef> = self
-            .module
-            .resolve_path(self.db, &path)
-            .take_values()?
-            .into();
-        let typable = typable?;
-        let ty = self.db.type_for_def(typable);
+        let resolved = self.module.resolve_path(self.db, &path).take_values()?;
+        let ty = self.db.type_for_def(resolved);
         let ty = self.insert_type_vars(ty);
         Some(ty)
     }
 
-    fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) {
+    fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) {
         let path = match path {
             Some(path) => path,
             None => return (Ty::Unknown, None),
         };
-        let typable: Option<TypableDef> = self
-            .module
-            .resolve_path(self.db, &path)
-            .take_types()
-            .and_then(|it| it.into());
-        let def = match typable {
-            None => return (Ty::Unknown, None),
-            Some(it) => it,
+        let def_id = match self.module.resolve_path(self.db, &path).take_types() {
+            Some(def_id) => def_id,
+            _ => return (Ty::Unknown, None),
         };
         // TODO remove the duplication between here and `Ty::from_path`?
         // TODO provide generics of function
@@ -1105,34 +1087,38 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
             self.impl_block.as_ref(),
             &generics,
             path,
-            def,
+            def_id,
         );
-        match def {
-            TypableDef::Struct(s) => {
+        match def_id.resolve(self.db) {
+            Def::Struct(s) => {
                 let ty = type_for_struct(self.db, s);
                 let ty = self.insert_type_vars(ty.apply_substs(substs));
-                (ty, Some(s.into()))
+                (ty, Some(def_id))
             }
-            TypableDef::EnumVariant(var) => {
-                let ty = type_for_enum_variant(self.db, var);
+            Def::EnumVariant(ev) => {
+                let ty = type_for_enum_variant(self.db, ev);
                 let ty = self.insert_type_vars(ty.apply_substs(substs));
-                (ty, Some(var.into()))
+                (ty, Some(def_id))
             }
-            TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None),
+            _ => (Ty::Unknown, None),
         }
     }
 
     fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> {
-        let (ty, def) = self.resolve_variant(path);
-        match def? {
-            VariantDef::Struct(s) => {
+        let (ty, def_id) = self.resolve_variant(path);
+        let def_id = def_id?;
+        let def = def_id.resolve(self.db);
+
+        match def {
+            Def::Struct(s) => {
                 let fields = s.fields(self.db);
                 Some((ty, fields))
             }
-            VariantDef::EnumVariant(var) => {
-                let fields = var.fields(self.db);
+            Def::EnumVariant(ev) => {
+                let fields = ev.fields(self.db);
                 Some((ty, fields))
             }
+            _ => None,
         }
     }
 
@@ -1230,7 +1216,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 .module
                 .resolve_path(self.db, &path)
                 .take_values()
-                .and_then(|module_def| module_def.into())
                 .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)),
             Pat::Bind {
                 mode,
@@ -1351,9 +1336,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
                 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
                 let method_ty = match resolved {
-                    Some(func) => {
-                        self.write_method_resolution(expr, func);
-                        self.db.type_for_def(func.into())
+                    Some(def_id) => {
+                        self.write_method_resolution(expr, def_id);
+                        self.db.type_for_def(def_id)
                     }
                     None => Ty::Unknown,
                 };
@@ -1422,7 +1407,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 for field in fields {
                     let field_ty = if let Some(def_id) = def_id {
                         self.db
-                            .type_for_field(def_id.into(), field.name.clone())
+                            .type_for_field(def_id, field.name.clone())
                             .unwrap_or(Ty::Unknown)
                             .subst(&substs)
                     } else {
@@ -1446,12 +1431,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                             i.and_then(|i| fields.get(i).cloned())
                         }
                         Ty::Adt {
-                            def_id: AdtDef::Struct(s),
-                            ref substs,
-                            ..
+                            def_id, ref substs, ..
                         } => self
                             .db
-                            .type_for_field(s.into(), name.clone())
+                            .type_for_field(def_id, name.clone())
                             .map(|ty| ty.subst(substs)),
                         _ => None,
                     })
@@ -1624,15 +1607,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
     }
 }
 
-pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
+pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> {
     db.check_canceled();
-    let body = func.body(db);
-    let scopes = db.fn_scopes(func);
-    let module = func.module(db);
-    let impl_block = func.impl_block(db);
+    let function = Function::new(def_id); // TODO: consts also need inference
+    let body = function.body(db);
+    let scopes = db.fn_scopes(def_id);
+    let module = function.module(db);
+    let impl_block = function.impl_block(db);
     let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block);
 
-    let signature = func.signature(db);
+    let signature = function.signature(db);
     ctx.collect_fn_signature(&signature);
 
     ctx.infer_body();
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9a571c2aaf..9f65c5fe1d 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -6,17 +6,19 @@ use std::sync::Arc;
 
 use rustc_hash::FxHashMap;
 
+use ra_db::SourceRootId;
+
 use crate::{
-    HirDatabase, module_tree::ModuleId, Module, Crate, Name, Function,
+    HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function,
     impl_block::{ImplId, ImplBlock, ImplItem},
-    generics::GenericParams,
-    ty::{AdtDef, Ty}
+    generics::GenericParams
 };
+use super::Ty;
 
 /// This is used as a key for indexing impls.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum TyFingerprint {
-    Adt(AdtDef),
+    Adt(DefId),
     // we'll also want to index impls for primitive types etc.
 }
 
@@ -35,7 +37,7 @@ impl TyFingerprint {
 #[derive(Debug, PartialEq, Eq)]
 pub struct CrateImplBlocks {
     /// To make sense of the ModuleIds, we need the source root.
-    krate: Crate,
+    source_root_id: SourceRootId,
     impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>,
 }
 
@@ -51,17 +53,14 @@ impl CrateImplBlocks {
             .into_iter()
             .flat_map(|i| i.iter())
             .map(move |(module_id, impl_id)| {
-                let module = Module {
-                    krate: self.krate.crate_id,
-                    module_id: *module_id,
-                };
-                let module_impl_blocks = db.impls_in_module(module);
+                let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id);
                 ImplBlock::from_id(module_impl_blocks, *impl_id)
             })
     }
 
-    fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) {
-        let module_impl_blocks = db.impls_in_module(module.clone());
+    fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
+        let module_id = module.def_id.loc(db).module_id;
+        let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id);
 
         for (impl_id, impl_data) in module_impl_blocks.impls.iter() {
             let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id);
@@ -82,13 +81,13 @@ impl CrateImplBlocks {
                     self.impls
                         .entry(target_ty_fp)
                         .or_insert_with(Vec::new)
-                        .push((module.module_id, impl_id));
+                        .push((module_id, impl_id));
                 }
             }
         }
 
         for child in module.children(db) {
-            self.collect_recursive(db, &child);
+            self.collect_recursive(db, child);
         }
     }
 
@@ -96,12 +95,15 @@ impl CrateImplBlocks {
         db: &impl HirDatabase,
         krate: Crate,
     ) -> Arc<CrateImplBlocks> {
+        let crate_graph = db.crate_graph();
+        let file_id = crate_graph.crate_root(krate.crate_id);
+        let source_root_id = db.file_source_root(file_id);
         let mut crate_impl_blocks = CrateImplBlocks {
-            krate: krate.clone(),
+            source_root_id,
             impls: FxHashMap::default(),
         };
         if let Some(module) = krate.root_module(db) {
-            crate_impl_blocks.collect_recursive(db, &module);
+            crate_impl_blocks.collect_recursive(db, module);
         }
         Arc::new(crate_impl_blocks)
     }
@@ -118,11 +120,11 @@ impl Ty {
     // TODO: cache this as a query?
     // - if so, what signature? (TyFingerprint, Name)?
     // - or maybe cache all names and def_ids of methods per fingerprint?
-    pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<Function> {
+    pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<DefId> {
         self.iterate_methods(db, |f| {
             let sig = f.signature(db);
             if sig.name() == name && sig.has_self_param() {
-                Some(f)
+                Some(f.def_id())
             } else {
                 None
             }
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 6a9358d333..07007d03fc 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -1,4 +1,4 @@
-use hir::{Ty, AdtDef};
+use hir::{Ty, Def};
 
 use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind};
 use crate::completion::completion_item::CompletionKind;
@@ -28,8 +28,8 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
             Ty::Adt {
                 def_id, ref substs, ..
             } => {
-                match def_id {
-                    AdtDef::Struct(s) => {
+                match def_id.resolve(ctx.db) {
+                    Def::Struct(s) => {
                         for field in s.fields(ctx.db) {
                             CompletionItem::new(
                                 CompletionKind::Reference,
@@ -41,9 +41,8 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
                             .add_to(acc);
                         }
                     }
-
                     // TODO unions
-                    AdtDef::Enum(_) => (),
+                    _ => {}
                 }
             }
             Ty::Tuple(fields) => {
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index e72586e2e5..e44b76c4a9 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -13,8 +13,8 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
         Some(it) => it,
         None => return,
     };
-    match def_id {
-        hir::ModuleDef::Module(module) => {
+    match def_id.resolve(ctx.db) {
+        hir::Def::Module(module) => {
             let module_scope = module.scope(ctx.db);
             for (name, res) in module_scope.entries() {
                 CompletionItem::new(
@@ -26,7 +26,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                 .add_to(acc);
             }
         }
-        hir::ModuleDef::Enum(e) => {
+        hir::Def::Enum(e) => {
             e.variants(ctx.db)
                 .into_iter()
                 .for_each(|(variant_name, variant)| {
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index 578af6e5b3..ca2069e2a7 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -127,7 +127,7 @@ impl<'a> CompletionContext<'a> {
             .ancestors()
             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
             .find_map(ast::FnDef::cast);
-        match (self.module, self.function_syntax) {
+        match (&self.module, self.function_syntax) {
             (Some(module), Some(fn_def)) => {
                 let function = source_binder::function_from_module(self.db, module, fn_def);
                 self.function = Some(function);
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index 3ba6c33ee6..18c151932a 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -1,4 +1,6 @@
-use hir::{Docs, Documentation};
+use hir::{Docs, Documentation, PerNs};
+
+use crate::completion::completion_context::CompletionContext;
 use ra_syntax::{
     ast::{self, AstNode},
     TextRange,
@@ -6,8 +8,6 @@ use ra_syntax::{
 use ra_text_edit::TextEdit;
 use test_utils::tested_by;
 
-use crate::completion::completion_context::CompletionContext;
-
 /// `CompletionItem` describes a single completion variant in the editor pop-up.
 /// It is basically a POD with various properties. To construct a
 /// `CompletionItem`, use `new` method and the `Builder` struct.
@@ -209,24 +209,41 @@ impl Builder {
         ctx: &CompletionContext,
         resolution: &hir::Resolution,
     ) -> Builder {
-        let def = resolution
-            .def_id
-            .take_types()
-            .or(resolution.def_id.take_values());
-        let def = match def {
-            None => return self,
-            Some(it) => it,
-        };
-        let (kind, docs) = match def {
-            hir::ModuleDef::Module(_) => (CompletionItemKind::Module, None),
-            hir::ModuleDef::Function(func) => return self.from_function(ctx, func),
-            hir::ModuleDef::Struct(it) => (CompletionItemKind::Struct, it.docs(ctx.db)),
-            hir::ModuleDef::Enum(it) => (CompletionItemKind::Enum, it.docs(ctx.db)),
-            hir::ModuleDef::EnumVariant(it) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
-            hir::ModuleDef::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)),
-            hir::ModuleDef::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)),
-            hir::ModuleDef::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)),
-            hir::ModuleDef::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
+        let resolved = resolution.def_id.map(|d| d.resolve(ctx.db));
+        let (kind, docs) = match resolved {
+            PerNs {
+                types: Some(hir::Def::Module(..)),
+                ..
+            } => (CompletionItemKind::Module, None),
+            PerNs {
+                types: Some(hir::Def::Struct(s)),
+                ..
+            } => (CompletionItemKind::Struct, s.docs(ctx.db)),
+            PerNs {
+                types: Some(hir::Def::Enum(e)),
+                ..
+            } => (CompletionItemKind::Enum, e.docs(ctx.db)),
+            PerNs {
+                types: Some(hir::Def::Trait(t)),
+                ..
+            } => (CompletionItemKind::Trait, t.docs(ctx.db)),
+            PerNs {
+                types: Some(hir::Def::Type(t)),
+                ..
+            } => (CompletionItemKind::TypeAlias, t.docs(ctx.db)),
+            PerNs {
+                values: Some(hir::Def::Const(c)),
+                ..
+            } => (CompletionItemKind::Const, c.docs(ctx.db)),
+            PerNs {
+                values: Some(hir::Def::Static(s)),
+                ..
+            } => (CompletionItemKind::Static, s.docs(ctx.db)),
+            PerNs {
+                values: Some(hir::Def::Function(function)),
+                ..
+            } => return self.from_function(ctx, function),
+            _ => return self,
         };
         self.kind = Some(kind);
         self.documentation = docs;
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs
index bff6b7237a..ba0eb1cb8a 100644
--- a/crates/ra_ide_api/src/db.rs
+++ b/crates/ra_ide_api/src/db.rs
@@ -72,7 +72,6 @@ salsa::database_storage! {
             fn file_relative_path() for ra_db::FileRelativePathQuery;
             fn file_source_root() for ra_db::FileSourceRootQuery;
             fn source_root() for ra_db::SourceRootQuery;
-            fn source_root_crates() for ra_db::SourceRootCratesQuery;
             fn local_roots() for ra_db::LocalRootsQuery;
             fn library_roots() for ra_db::LibraryRootsQuery;
             fn crate_graph() for ra_db::CrateGraphQuery;
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 46bdde00d7..b1becca031 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -63,11 +63,13 @@ pub(crate) fn reference_definition(
             let infer_result = function.infer(db);
             let syntax_mapping = function.body_syntax_mapping(db);
             let expr = ast::Expr::cast(method_call.syntax()).unwrap();
-            if let Some(func) = syntax_mapping
+            if let Some(def_id) = syntax_mapping
                 .node_expr(expr)
                 .and_then(|it| infer_result.method_resolution(it))
             {
-                return Exact(NavigationTarget::from_function(db, func));
+                if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) {
+                    return Exact(target);
+                }
             };
         }
     }
@@ -82,7 +84,7 @@ pub(crate) fn reference_definition(
         {
             let resolved = module.resolve_path(db, &path);
             if let Some(def_id) = resolved.take_types().or(resolved.take_values()) {
-                if let Some(target) = NavigationTarget::from_def(db, def_id) {
+                if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) {
                     return Exact(target);
                 }
             }
diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs
index c5be8e01be..21c15c0c00 100644
--- a/crates/ra_ide_api/src/navigation_target.rs
+++ b/crates/ra_ide_api/src/navigation_target.rs
@@ -3,7 +3,7 @@ use ra_syntax::{
     SyntaxNode, AstNode, SmolStr, TextRange, ast,
     SyntaxKind::{self, NAME},
 };
-use hir::{ModuleSource};
+use hir::{Def, ModuleSource};
 
 use crate::{FileSymbol, db::RootDatabase};
 
@@ -96,69 +96,45 @@ impl NavigationTarget {
         NavigationTarget::from_module(db, module)
     }
 
-    pub(crate) fn from_function(db: &RootDatabase, func: hir::Function) -> NavigationTarget {
-        let (file_id, fn_def) = func.source(db);
-        NavigationTarget::from_named(file_id.original_file(db), &*fn_def)
-    }
-
     // TODO once Def::Item is gone, this should be able to always return a NavigationTarget
-    pub(crate) fn from_def(
-        db: &RootDatabase,
-        module_def: hir::ModuleDef,
-    ) -> Option<NavigationTarget> {
-        match module_def {
-            hir::ModuleDef::Module(module) => Some(NavigationTarget::from_module(db, module)),
-            hir::ModuleDef::Function(func) => Some(NavigationTarget::from_function(db, func)),
-            hir::ModuleDef::Struct(s) => {
+    pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Option<NavigationTarget> {
+        let res = match def {
+            Def::Struct(s) => {
                 let (file_id, node) = s.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Const(s) => {
-                let (file_id, node) = s.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::Enum(e) => {
+                let (file_id, node) = e.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Static(s) => {
-                let (file_id, node) = s.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::EnumVariant(ev) => {
+                let (file_id, node) = ev.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Enum(e) => {
-                let (file_id, node) = e.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::Function(f) => {
+                let (file_id, node) = f.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::EnumVariant(var) => {
-                let (file_id, node) = var.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::Trait(f) => {
+                let (file_id, node) = f.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Trait(e) => {
-                let (file_id, node) = e.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::Type(f) => {
+                let (file_id, node) = f.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Type(e) => {
-                let (file_id, node) = e.source(db);
-                Some(NavigationTarget::from_named(
-                    file_id.original_file(db),
-                    &*node,
-                ))
+            Def::Static(f) => {
+                let (file_id, node) = f.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-        }
+            Def::Const(f) => {
+                let (file_id, node) = f.source(db);
+                NavigationTarget::from_named(file_id.original_file(db), &*node)
+            }
+            Def::Module(m) => NavigationTarget::from_module(db, m),
+            Def::Item => return None,
+        };
+        Some(res)
     }
 
     #[cfg(test)]
diff --git a/crates/ra_ide_api/src/rename.rs b/crates/ra_ide_api/src/rename.rs
index 5b767addd3..53dc273c63 100644
--- a/crates/ra_ide_api/src/rename.rs
+++ b/crates/ra_ide_api/src/rename.rs
@@ -57,6 +57,7 @@ fn rename_mod(
 ) -> Option<SourceChange> {
     let mut source_file_edits = Vec::new();
     let mut file_system_edits = Vec::new();
+
     if let Some(module) = module_from_declaration(db, position.file_id, &ast_module) {
         let (file_id, module_source) = module.definition_source(db);
         match module_source {
@@ -222,15 +223,11 @@ mod tests {
     fn test_rename_mod() {
         let (analysis, position) = analysis_and_position(
             "
-            //- /lib.rs
-            mod bar;
-
-            //- /bar.rs
-            mod foo<|>;
-
-            //- /bar/foo.rs
-            // emtpy
-            ",
+        //- /bar.rs
+        mod fo<|>o;
+        //- /bar/foo.rs
+        // emtpy
+    ",
         );
         let new_name = "foo2";
         let source_change = analysis.rename(position, new_name).unwrap();
@@ -241,11 +238,11 @@ mod tests {
     fn test_rename_mod_in_dir() {
         let (analysis, position) = analysis_and_position(
             "
-            //- /lib.rs
-            mod fo<|>o;
-            //- /foo/mod.rs
-            // emtpy
-            ",
+        //- /lib.rs
+        mod fo<|>o;
+        //- /foo/mod.rs
+        // emtpy
+    ",
         );
         let new_name = "foo2";
         let source_change = analysis.rename(position, new_name).unwrap();
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index fd65264b27..b92cc082ef 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -15,12 +15,13 @@ use crate::{
 /// conversion itself has zero runtime cost: ast and syntax nodes have exactly
 /// the same representation: a pointer to the tree root and a pointer to the
 /// node itself.
-pub trait AstNode: rowan::TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> {
+pub trait AstNode:
+    rowan::TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> + ToOwned<Owned = TreeArc<Self>>
+{
     fn cast(syntax: &SyntaxNode) -> Option<&Self>
     where
         Self: Sized;
     fn syntax(&self) -> &SyntaxNode;
-    fn to_owned(&self) -> TreeArc<Self>;
 }
 
 pub trait AstToken: AstNode {
@@ -430,13 +431,6 @@ impl StructDef {
 }
 
 impl EnumVariant {
-    pub fn parent_enum(&self) -> &EnumDef {
-        self.syntax()
-            .parent()
-            .and_then(|it| it.parent())
-            .and_then(EnumDef::cast)
-            .expect("EnumVariants are always nested in Enums")
-    }
     pub fn flavor(&self) -> StructFlavor {
         StructFlavor::from_node(self)
     }
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index a207f8429f..e39b588277 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -35,6 +35,10 @@ impl AstNode for ArgList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ArgList {
+    type Owned = TreeArc<ArgList>;
     fn to_owned(&self) -> TreeArc<ArgList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -63,6 +67,10 @@ impl AstNode for ArrayExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ArrayExpr {
+    type Owned = TreeArc<ArrayExpr>;
     fn to_owned(&self) -> TreeArc<ArrayExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -91,6 +99,10 @@ impl AstNode for ArrayType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ArrayType {
+    type Owned = TreeArc<ArrayType>;
     fn to_owned(&self) -> TreeArc<ArrayType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -123,6 +135,10 @@ impl AstNode for AssocTypeArg {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for AssocTypeArg {
+    type Owned = TreeArc<AssocTypeArg>;
     fn to_owned(&self) -> TreeArc<AssocTypeArg> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -155,6 +171,10 @@ impl AstNode for Attr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Attr {
+    type Owned = TreeArc<Attr>;
     fn to_owned(&self) -> TreeArc<Attr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -183,6 +203,10 @@ impl AstNode for BinExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for BinExpr {
+    type Owned = TreeArc<BinExpr>;
     fn to_owned(&self) -> TreeArc<BinExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -207,6 +231,10 @@ impl AstNode for BindPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for BindPat {
+    type Owned = TreeArc<BindPat>;
     fn to_owned(&self) -> TreeArc<BindPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -236,6 +264,10 @@ impl AstNode for Block {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Block {
+    type Owned = TreeArc<Block>;
     fn to_owned(&self) -> TreeArc<Block> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -268,6 +300,10 @@ impl AstNode for BlockExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for BlockExpr {
+    type Owned = TreeArc<BlockExpr>;
     fn to_owned(&self) -> TreeArc<BlockExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -296,6 +332,10 @@ impl AstNode for BreakExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for BreakExpr {
+    type Owned = TreeArc<BreakExpr>;
     fn to_owned(&self) -> TreeArc<BreakExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -324,6 +364,10 @@ impl AstNode for Byte {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Byte {
+    type Owned = TreeArc<Byte>;
     fn to_owned(&self) -> TreeArc<Byte> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -349,6 +393,10 @@ impl AstNode for ByteString {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ByteString {
+    type Owned = TreeArc<ByteString>;
     fn to_owned(&self) -> TreeArc<ByteString> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -374,6 +422,10 @@ impl AstNode for CallExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for CallExpr {
+    type Owned = TreeArc<CallExpr>;
     fn to_owned(&self) -> TreeArc<CallExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -403,6 +455,10 @@ impl AstNode for CastExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for CastExpr {
+    type Owned = TreeArc<CastExpr>;
     fn to_owned(&self) -> TreeArc<CastExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -435,6 +491,10 @@ impl AstNode for Char {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Char {
+    type Owned = TreeArc<Char>;
     fn to_owned(&self) -> TreeArc<Char> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -460,6 +520,10 @@ impl AstNode for Comment {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Comment {
+    type Owned = TreeArc<Comment>;
     fn to_owned(&self) -> TreeArc<Comment> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -485,6 +549,10 @@ impl AstNode for Condition {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Condition {
+    type Owned = TreeArc<Condition>;
     fn to_owned(&self) -> TreeArc<Condition> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -517,6 +585,10 @@ impl AstNode for ConstDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ConstDef {
+    type Owned = TreeArc<ConstDef>;
     fn to_owned(&self) -> TreeArc<ConstDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -546,6 +618,10 @@ impl AstNode for ContinueExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ContinueExpr {
+    type Owned = TreeArc<ContinueExpr>;
     fn to_owned(&self) -> TreeArc<ContinueExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -570,6 +646,10 @@ impl AstNode for DynTraitType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for DynTraitType {
+    type Owned = TreeArc<DynTraitType>;
     fn to_owned(&self) -> TreeArc<DynTraitType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -594,6 +674,10 @@ impl AstNode for EnumDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for EnumDef {
+    type Owned = TreeArc<EnumDef>;
     fn to_owned(&self) -> TreeArc<EnumDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -627,6 +711,10 @@ impl AstNode for EnumVariant {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for EnumVariant {
+    type Owned = TreeArc<EnumVariant>;
     fn to_owned(&self) -> TreeArc<EnumVariant> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -657,6 +745,10 @@ impl AstNode for EnumVariantList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for EnumVariantList {
+    type Owned = TreeArc<EnumVariantList>;
     fn to_owned(&self) -> TreeArc<EnumVariantList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -742,6 +834,10 @@ impl AstNode for Expr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Expr {
+    type Owned = TreeArc<Expr>;
     fn to_owned(&self) -> TreeArc<Expr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -800,6 +896,10 @@ impl AstNode for ExprStmt {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ExprStmt {
+    type Owned = TreeArc<ExprStmt>;
     fn to_owned(&self) -> TreeArc<ExprStmt> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -828,6 +928,10 @@ impl AstNode for ExternCrateItem {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ExternCrateItem {
+    type Owned = TreeArc<ExternCrateItem>;
     fn to_owned(&self) -> TreeArc<ExternCrateItem> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -852,6 +956,10 @@ impl AstNode for FalseKw {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FalseKw {
+    type Owned = TreeArc<FalseKw>;
     fn to_owned(&self) -> TreeArc<FalseKw> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -877,6 +985,10 @@ impl AstNode for FieldExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FieldExpr {
+    type Owned = TreeArc<FieldExpr>;
     fn to_owned(&self) -> TreeArc<FieldExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -909,6 +1021,10 @@ impl AstNode for FieldPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FieldPat {
+    type Owned = TreeArc<FieldPat>;
     fn to_owned(&self) -> TreeArc<FieldPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -938,6 +1054,10 @@ impl AstNode for FieldPatList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FieldPatList {
+    type Owned = TreeArc<FieldPatList>;
     fn to_owned(&self) -> TreeArc<FieldPatList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -970,6 +1090,10 @@ impl AstNode for FloatNumber {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FloatNumber {
+    type Owned = TreeArc<FloatNumber>;
     fn to_owned(&self) -> TreeArc<FloatNumber> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -995,6 +1119,10 @@ impl AstNode for FnDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FnDef {
+    type Owned = TreeArc<FnDef>;
     fn to_owned(&self) -> TreeArc<FnDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1036,6 +1164,10 @@ impl AstNode for FnPointerType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for FnPointerType {
+    type Owned = TreeArc<FnPointerType>;
     fn to_owned(&self) -> TreeArc<FnPointerType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1068,6 +1200,10 @@ impl AstNode for ForExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ForExpr {
+    type Owned = TreeArc<ForExpr>;
     fn to_owned(&self) -> TreeArc<ForExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1101,6 +1237,10 @@ impl AstNode for ForType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ForType {
+    type Owned = TreeArc<ForType>;
     fn to_owned(&self) -> TreeArc<ForType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1129,6 +1269,10 @@ impl AstNode for IfExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for IfExpr {
+    type Owned = TreeArc<IfExpr>;
     fn to_owned(&self) -> TreeArc<IfExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1157,6 +1301,10 @@ impl AstNode for ImplBlock {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ImplBlock {
+    type Owned = TreeArc<ImplBlock>;
     fn to_owned(&self) -> TreeArc<ImplBlock> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1194,6 +1342,10 @@ impl AstNode for ImplItem {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ImplItem {
+    type Owned = TreeArc<ImplItem>;
     fn to_owned(&self) -> TreeArc<ImplItem> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1228,6 +1380,10 @@ impl AstNode for ImplTraitType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ImplTraitType {
+    type Owned = TreeArc<ImplTraitType>;
     fn to_owned(&self) -> TreeArc<ImplTraitType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1252,6 +1408,10 @@ impl AstNode for IndexExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for IndexExpr {
+    type Owned = TreeArc<IndexExpr>;
     fn to_owned(&self) -> TreeArc<IndexExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1276,6 +1436,10 @@ impl AstNode for IntNumber {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for IntNumber {
+    type Owned = TreeArc<IntNumber>;
     fn to_owned(&self) -> TreeArc<IntNumber> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1301,6 +1465,10 @@ impl AstNode for ItemList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ItemList {
+    type Owned = TreeArc<ItemList>;
     fn to_owned(&self) -> TreeArc<ItemList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1331,6 +1499,10 @@ impl AstNode for Label {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Label {
+    type Owned = TreeArc<Label>;
     fn to_owned(&self) -> TreeArc<Label> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1355,6 +1527,10 @@ impl AstNode for LambdaExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LambdaExpr {
+    type Owned = TreeArc<LambdaExpr>;
     fn to_owned(&self) -> TreeArc<LambdaExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1387,6 +1563,10 @@ impl AstNode for LetStmt {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LetStmt {
+    type Owned = TreeArc<LetStmt>;
     fn to_owned(&self) -> TreeArc<LetStmt> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1423,6 +1603,10 @@ impl AstNode for Lifetime {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Lifetime {
+    type Owned = TreeArc<Lifetime>;
     fn to_owned(&self) -> TreeArc<Lifetime> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1448,6 +1632,10 @@ impl AstNode for LifetimeArg {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LifetimeArg {
+    type Owned = TreeArc<LifetimeArg>;
     fn to_owned(&self) -> TreeArc<LifetimeArg> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1476,6 +1664,10 @@ impl AstNode for LifetimeParam {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LifetimeParam {
+    type Owned = TreeArc<LifetimeParam>;
     fn to_owned(&self) -> TreeArc<LifetimeParam> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1504,6 +1696,10 @@ impl AstNode for Literal {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Literal {
+    type Owned = TreeArc<Literal>;
     fn to_owned(&self) -> TreeArc<Literal> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1555,6 +1751,10 @@ impl AstNode for LiteralExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LiteralExpr {
+    type Owned = TreeArc<LiteralExpr>;
     fn to_owned(&self) -> TreeArc<LiteralExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1596,6 +1796,10 @@ impl AstNode for LoopExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for LoopExpr {
+    type Owned = TreeArc<LoopExpr>;
     fn to_owned(&self) -> TreeArc<LoopExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1621,6 +1825,10 @@ impl AstNode for MacroCall {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MacroCall {
+    type Owned = TreeArc<MacroCall>;
     fn to_owned(&self) -> TreeArc<MacroCall> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1653,6 +1861,10 @@ impl AstNode for MatchArm {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MatchArm {
+    type Owned = TreeArc<MatchArm>;
     fn to_owned(&self) -> TreeArc<MatchArm> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1689,6 +1901,10 @@ impl AstNode for MatchArmList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MatchArmList {
+    type Owned = TreeArc<MatchArmList>;
     fn to_owned(&self) -> TreeArc<MatchArmList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1717,6 +1933,10 @@ impl AstNode for MatchExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MatchExpr {
+    type Owned = TreeArc<MatchExpr>;
     fn to_owned(&self) -> TreeArc<MatchExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1749,6 +1969,10 @@ impl AstNode for MatchGuard {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MatchGuard {
+    type Owned = TreeArc<MatchGuard>;
     fn to_owned(&self) -> TreeArc<MatchGuard> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1773,6 +1997,10 @@ impl AstNode for MethodCallExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for MethodCallExpr {
+    type Owned = TreeArc<MethodCallExpr>;
     fn to_owned(&self) -> TreeArc<MethodCallExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1806,6 +2034,10 @@ impl AstNode for Module {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Module {
+    type Owned = TreeArc<Module>;
     fn to_owned(&self) -> TreeArc<Module> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1863,6 +2095,10 @@ impl AstNode for ModuleItem {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ModuleItem {
+    type Owned = TreeArc<ModuleItem>;
     fn to_owned(&self) -> TreeArc<ModuleItem> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1905,6 +2141,10 @@ impl AstNode for Name {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Name {
+    type Owned = TreeArc<Name>;
     fn to_owned(&self) -> TreeArc<Name> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1929,6 +2169,10 @@ impl AstNode for NameRef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NameRef {
+    type Owned = TreeArc<NameRef>;
     fn to_owned(&self) -> TreeArc<NameRef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1953,6 +2197,10 @@ impl AstNode for NamedField {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NamedField {
+    type Owned = TreeArc<NamedField>;
     fn to_owned(&self) -> TreeArc<NamedField> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -1985,6 +2233,10 @@ impl AstNode for NamedFieldDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NamedFieldDef {
+    type Owned = TreeArc<NamedFieldDef>;
     fn to_owned(&self) -> TreeArc<NamedFieldDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2016,6 +2268,10 @@ impl AstNode for NamedFieldDefList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NamedFieldDefList {
+    type Owned = TreeArc<NamedFieldDefList>;
     fn to_owned(&self) -> TreeArc<NamedFieldDefList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2044,6 +2300,10 @@ impl AstNode for NamedFieldList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NamedFieldList {
+    type Owned = TreeArc<NamedFieldList>;
     fn to_owned(&self) -> TreeArc<NamedFieldList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2072,6 +2332,10 @@ impl AstNode for NeverType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NeverType {
+    type Owned = TreeArc<NeverType>;
     fn to_owned(&self) -> TreeArc<NeverType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2103,6 +2367,10 @@ impl AstNode for NominalDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for NominalDef {
+    type Owned = TreeArc<NominalDef>;
     fn to_owned(&self) -> TreeArc<NominalDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2139,6 +2407,10 @@ impl AstNode for Param {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Param {
+    type Owned = TreeArc<Param>;
     fn to_owned(&self) -> TreeArc<Param> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2171,6 +2443,10 @@ impl AstNode for ParamList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ParamList {
+    type Owned = TreeArc<ParamList>;
     fn to_owned(&self) -> TreeArc<ParamList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2203,6 +2479,10 @@ impl AstNode for ParenExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ParenExpr {
+    type Owned = TreeArc<ParenExpr>;
     fn to_owned(&self) -> TreeArc<ParenExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2231,6 +2511,10 @@ impl AstNode for ParenType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ParenType {
+    type Owned = TreeArc<ParenType>;
     fn to_owned(&self) -> TreeArc<ParenType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2280,6 +2564,10 @@ impl AstNode for Pat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Pat {
+    type Owned = TreeArc<Pat>;
     fn to_owned(&self) -> TreeArc<Pat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2320,6 +2608,10 @@ impl AstNode for Path {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Path {
+    type Owned = TreeArc<Path>;
     fn to_owned(&self) -> TreeArc<Path> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2352,6 +2644,10 @@ impl AstNode for PathExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PathExpr {
+    type Owned = TreeArc<PathExpr>;
     fn to_owned(&self) -> TreeArc<PathExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2380,6 +2676,10 @@ impl AstNode for PathPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PathPat {
+    type Owned = TreeArc<PathPat>;
     fn to_owned(&self) -> TreeArc<PathPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2408,6 +2708,10 @@ impl AstNode for PathSegment {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PathSegment {
+    type Owned = TreeArc<PathSegment>;
     fn to_owned(&self) -> TreeArc<PathSegment> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2440,6 +2744,10 @@ impl AstNode for PathType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PathType {
+    type Owned = TreeArc<PathType>;
     fn to_owned(&self) -> TreeArc<PathType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2468,6 +2776,10 @@ impl AstNode for PlaceholderPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PlaceholderPat {
+    type Owned = TreeArc<PlaceholderPat>;
     fn to_owned(&self) -> TreeArc<PlaceholderPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2492,6 +2804,10 @@ impl AstNode for PlaceholderType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PlaceholderType {
+    type Owned = TreeArc<PlaceholderType>;
     fn to_owned(&self) -> TreeArc<PlaceholderType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2516,6 +2832,10 @@ impl AstNode for PointerType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PointerType {
+    type Owned = TreeArc<PointerType>;
     fn to_owned(&self) -> TreeArc<PointerType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2544,6 +2864,10 @@ impl AstNode for PosField {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PosField {
+    type Owned = TreeArc<PosField>;
     fn to_owned(&self) -> TreeArc<PosField> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2574,6 +2898,10 @@ impl AstNode for PosFieldList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PosFieldList {
+    type Owned = TreeArc<PosFieldList>;
     fn to_owned(&self) -> TreeArc<PosFieldList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2602,6 +2930,10 @@ impl AstNode for PrefixExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for PrefixExpr {
+    type Owned = TreeArc<PrefixExpr>;
     fn to_owned(&self) -> TreeArc<PrefixExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2630,6 +2962,10 @@ impl AstNode for RangeExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RangeExpr {
+    type Owned = TreeArc<RangeExpr>;
     fn to_owned(&self) -> TreeArc<RangeExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2654,6 +2990,10 @@ impl AstNode for RangePat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RangePat {
+    type Owned = TreeArc<RangePat>;
     fn to_owned(&self) -> TreeArc<RangePat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2678,6 +3018,10 @@ impl AstNode for RawByteString {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RawByteString {
+    type Owned = TreeArc<RawByteString>;
     fn to_owned(&self) -> TreeArc<RawByteString> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2703,6 +3047,10 @@ impl AstNode for RawString {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RawString {
+    type Owned = TreeArc<RawString>;
     fn to_owned(&self) -> TreeArc<RawString> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2728,6 +3076,10 @@ impl AstNode for RefExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RefExpr {
+    type Owned = TreeArc<RefExpr>;
     fn to_owned(&self) -> TreeArc<RefExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2756,6 +3108,10 @@ impl AstNode for RefPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RefPat {
+    type Owned = TreeArc<RefPat>;
     fn to_owned(&self) -> TreeArc<RefPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2784,6 +3140,10 @@ impl AstNode for ReferenceType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ReferenceType {
+    type Owned = TreeArc<ReferenceType>;
     fn to_owned(&self) -> TreeArc<ReferenceType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2812,6 +3172,10 @@ impl AstNode for RetType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for RetType {
+    type Owned = TreeArc<RetType>;
     fn to_owned(&self) -> TreeArc<RetType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2840,6 +3204,10 @@ impl AstNode for ReturnExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for ReturnExpr {
+    type Owned = TreeArc<ReturnExpr>;
     fn to_owned(&self) -> TreeArc<ReturnExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2868,6 +3236,10 @@ impl AstNode for SelfKw {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for SelfKw {
+    type Owned = TreeArc<SelfKw>;
     fn to_owned(&self) -> TreeArc<SelfKw> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2892,6 +3264,10 @@ impl AstNode for SelfParam {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for SelfParam {
+    type Owned = TreeArc<SelfParam>;
     fn to_owned(&self) -> TreeArc<SelfParam> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2924,6 +3300,10 @@ impl AstNode for SlicePat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for SlicePat {
+    type Owned = TreeArc<SlicePat>;
     fn to_owned(&self) -> TreeArc<SlicePat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2948,6 +3328,10 @@ impl AstNode for SliceType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for SliceType {
+    type Owned = TreeArc<SliceType>;
     fn to_owned(&self) -> TreeArc<SliceType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -2976,6 +3360,10 @@ impl AstNode for SourceFile {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for SourceFile {
+    type Owned = TreeArc<SourceFile>;
     fn to_owned(&self) -> TreeArc<SourceFile> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3006,6 +3394,10 @@ impl AstNode for StaticDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for StaticDef {
+    type Owned = TreeArc<StaticDef>;
     fn to_owned(&self) -> TreeArc<StaticDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3042,6 +3434,10 @@ impl AstNode for Stmt {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Stmt {
+    type Owned = TreeArc<Stmt>;
     fn to_owned(&self) -> TreeArc<Stmt> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3075,6 +3471,10 @@ impl AstNode for String {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for String {
+    type Owned = TreeArc<String>;
     fn to_owned(&self) -> TreeArc<String> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3100,6 +3500,10 @@ impl AstNode for StructDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for StructDef {
+    type Owned = TreeArc<StructDef>;
     fn to_owned(&self) -> TreeArc<StructDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3129,6 +3533,10 @@ impl AstNode for StructLit {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for StructLit {
+    type Owned = TreeArc<StructLit>;
     fn to_owned(&self) -> TreeArc<StructLit> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3165,6 +3573,10 @@ impl AstNode for StructPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for StructPat {
+    type Owned = TreeArc<StructPat>;
     fn to_owned(&self) -> TreeArc<StructPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3197,6 +3609,10 @@ impl AstNode for TokenTree {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TokenTree {
+    type Owned = TreeArc<TokenTree>;
     fn to_owned(&self) -> TreeArc<TokenTree> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3221,6 +3637,10 @@ impl AstNode for TraitDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TraitDef {
+    type Owned = TreeArc<TraitDef>;
     fn to_owned(&self) -> TreeArc<TraitDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3229,7 +3649,6 @@ impl ast::VisibilityOwner for TraitDef {}
 impl ast::NameOwner for TraitDef {}
 impl ast::AttrsOwner for TraitDef {}
 impl ast::DocCommentsOwner for TraitDef {}
-impl ast::TypeParamsOwner for TraitDef {}
 impl TraitDef {}
 
 // TrueKw
@@ -3250,6 +3669,10 @@ impl AstNode for TrueKw {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TrueKw {
+    type Owned = TreeArc<TrueKw>;
     fn to_owned(&self) -> TreeArc<TrueKw> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3275,6 +3698,10 @@ impl AstNode for TryExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TryExpr {
+    type Owned = TreeArc<TryExpr>;
     fn to_owned(&self) -> TreeArc<TryExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3303,6 +3730,10 @@ impl AstNode for TupleExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TupleExpr {
+    type Owned = TreeArc<TupleExpr>;
     fn to_owned(&self) -> TreeArc<TupleExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3331,6 +3762,10 @@ impl AstNode for TuplePat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TuplePat {
+    type Owned = TreeArc<TuplePat>;
     fn to_owned(&self) -> TreeArc<TuplePat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3359,6 +3794,10 @@ impl AstNode for TupleStructPat {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TupleStructPat {
+    type Owned = TreeArc<TupleStructPat>;
     fn to_owned(&self) -> TreeArc<TupleStructPat> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3391,6 +3830,10 @@ impl AstNode for TupleType {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TupleType {
+    type Owned = TreeArc<TupleType>;
     fn to_owned(&self) -> TreeArc<TupleType> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3419,6 +3862,10 @@ impl AstNode for TypeArg {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeArg {
+    type Owned = TreeArc<TypeArg>;
     fn to_owned(&self) -> TreeArc<TypeArg> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3447,6 +3894,10 @@ impl AstNode for TypeArgList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeArgList {
+    type Owned = TreeArc<TypeArgList>;
     fn to_owned(&self) -> TreeArc<TypeArgList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3483,6 +3934,10 @@ impl AstNode for TypeDef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeDef {
+    type Owned = TreeArc<TypeDef>;
     fn to_owned(&self) -> TreeArc<TypeDef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3512,6 +3967,10 @@ impl AstNode for TypeParam {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeParam {
+    type Owned = TreeArc<TypeParam>;
     fn to_owned(&self) -> TreeArc<TypeParam> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3537,6 +3996,10 @@ impl AstNode for TypeParamList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeParamList {
+    type Owned = TreeArc<TypeParamList>;
     fn to_owned(&self) -> TreeArc<TypeParamList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3598,6 +4061,10 @@ impl AstNode for TypeRef {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for TypeRef {
+    type Owned = TreeArc<TypeRef>;
     fn to_owned(&self) -> TreeArc<TypeRef> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3642,6 +4109,10 @@ impl AstNode for UseItem {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for UseItem {
+    type Owned = TreeArc<UseItem>;
     fn to_owned(&self) -> TreeArc<UseItem> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3670,6 +4141,10 @@ impl AstNode for UseTree {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for UseTree {
+    type Owned = TreeArc<UseTree>;
     fn to_owned(&self) -> TreeArc<UseTree> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3702,6 +4177,10 @@ impl AstNode for UseTreeList {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for UseTreeList {
+    type Owned = TreeArc<UseTreeList>;
     fn to_owned(&self) -> TreeArc<UseTreeList> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3730,6 +4209,10 @@ impl AstNode for Visibility {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Visibility {
+    type Owned = TreeArc<Visibility>;
     fn to_owned(&self) -> TreeArc<Visibility> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3754,6 +4237,10 @@ impl AstNode for WhereClause {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for WhereClause {
+    type Owned = TreeArc<WhereClause>;
     fn to_owned(&self) -> TreeArc<WhereClause> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3778,6 +4265,10 @@ impl AstNode for WhileExpr {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for WhileExpr {
+    type Owned = TreeArc<WhileExpr>;
     fn to_owned(&self) -> TreeArc<WhileExpr> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -3807,6 +4298,10 @@ impl AstNode for Whitespace {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for Whitespace {
+    type Owned = TreeArc<Whitespace>;
     fn to_owned(&self) -> TreeArc<Whitespace> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera
index bf9db4ee87..ea0fc35fd7 100644
--- a/crates/ra_syntax/src/ast/generated.rs.tera
+++ b/crates/ra_syntax/src/ast/generated.rs.tera
@@ -48,6 +48,10 @@ impl AstNode for {{ node }} {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for {{ node }} {
+    type Owned = TreeArc<{{ node }}>;
     fn to_owned(&self) -> TreeArc<{{ node }}> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
@@ -79,6 +83,10 @@ impl AstNode for {{ node }} {
         }
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+
+impl ToOwned for {{ node }} {
+    type Owned = TreeArc<{{ node }}>;
     fn to_owned(&self) -> TreeArc<{{ node }}> { TreeArc::cast(self.syntax.to_owned()) }
 }
 
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index dedefea591..c5297e46dd 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -280,7 +280,7 @@ Grammar(
         ], options: [["variant_list", "EnumVariantList"]] ),
         "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
         "EnumVariant": ( traits: ["NameOwner", "DocCommentsOwner"], options: ["Expr"] ),
-        "TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner", "TypeParamsOwner"] ),
+        "TraitDef": ( traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner"] ),
         "Module": (
             traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ],
             options: [ "ItemList" ]
@@ -489,7 +489,7 @@ Grammar(
         ),
 
         "RefPat": ( options: [ "Pat" ]),
-        "BindPat": (
+        "BindPat": ( 
             options: [ "Pat" ],
             traits: ["NameOwner"]
         ),
diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs
index a7bfb80e23..ed48739f8a 100644
--- a/crates/ra_syntax/src/yellow.rs
+++ b/crates/ra_syntax/src/yellow.rs
@@ -2,10 +2,11 @@ mod builder;
 pub mod syntax_error;
 mod syntax_text;
 
+use std::{fmt, borrow::Borrow};
+
 use self::syntax_text::SyntaxText;
 use crate::{SmolStr, SyntaxKind, TextRange};
 use rowan::{Types, TransparentNewType};
-use std::fmt;
 
 pub(crate) use self::builder::GreenBuilder;
 pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location};
@@ -25,6 +26,12 @@ pub struct TreeArc<T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>>(
     pub(crate) rowan::TreeArc<RaTypes, T>,
 );
 
+impl<T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>> Borrow<T> for TreeArc<T> {
+    fn borrow(&self) -> &T {
+        &*self
+    }
+}
+
 impl<T> TreeArc<T>
 where
     T: TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>>,
@@ -124,6 +131,14 @@ impl SyntaxNode {
     }
 }
 
+impl ToOwned for SyntaxNode {
+    type Owned = TreeArc<SyntaxNode>;
+    fn to_owned(&self) -> TreeArc<SyntaxNode> {
+        let ptr = TreeArc(self.0.to_owned());
+        TreeArc::cast(ptr)
+    }
+}
+
 impl SyntaxNode {
     pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
         self.0.root_data()
@@ -133,11 +148,6 @@ impl SyntaxNode {
         self.0.replace_self(replacement)
     }
 
-    pub fn to_owned(&self) -> TreeArc<SyntaxNode> {
-        let ptr = TreeArc(self.0.to_owned());
-        TreeArc::cast(ptr)
-    }
-
     pub fn kind(&self) -> SyntaxKind {
         self.0.kind()
     }


Test patch:
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs
index 9322bf08ce..e920074533 100644
--- a/crates/ra_hir/src/nameres/tests.rs
+++ b/crates/ra_hir/src/nameres/tests.rs
@@ -1,6 +1,6 @@
 use std::sync::Arc;
 
-use ra_db::{CrateGraph, SourceRootId, salsa::Database};
+use ra_db::{FilesDatabase, CrateGraph, SourceRootId, salsa::Database};
 use relative_path::RelativePath;
 use test_utils::{assert_eq_text, covers};
 
@@ -13,10 +13,10 @@ use crate::{
 
 fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
     let (db, pos) = MockDatabase::with_position(fixture);
+    let source_root = db.file_source_root(pos.file_id);
     let module = crate::source_binder::module_from_position(&db, pos).unwrap();
-    let krate = module.krate(&db).unwrap();
-    let module_id = module.module_id;
-    (db.item_map(krate.crate_id), module_id)
+    let module_id = module.def_id.loc(&db).module_id;
+    (db.item_map(source_root), module_id)
 }
 
 fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) {
@@ -238,13 +238,14 @@ fn item_map_across_crates() {
 
     db.set_crate_graph(crate_graph);
 
+    let source_root = db.file_source_root(main_id);
     let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
-    let krate = module.krate(&db).unwrap();
-    let item_map = db.item_map(krate.crate_id);
+    let module_id = module.def_id.loc(&db).module_id;
+    let item_map = db.item_map(source_root);
 
     check_module_item_map(
         &item_map,
-        module.module_id,
+        module_id,
         "
             Baz: t v
             test_crate: t
@@ -291,12 +292,12 @@ fn import_across_source_roots() {
     db.set_crate_graph(crate_graph);
 
     let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
-    let krate = module.krate(&db).unwrap();
-    let item_map = db.item_map(krate.crate_id);
+    let module_id = module.def_id.loc(&db).module_id;
+    let item_map = db.item_map(source_root);
 
     check_module_item_map(
         &item_map,
-        module.module_id,
+        module_id,
         "
             C: t v
             test_crate: t
@@ -332,13 +333,14 @@ fn reexport_across_crates() {
 
     db.set_crate_graph(crate_graph);
 
+    let source_root = db.file_source_root(main_id);
     let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap();
-    let krate = module.krate(&db).unwrap();
-    let item_map = db.item_map(krate.crate_id);
+    let module_id = module.def_id.loc(&db).module_id;
+    let item_map = db.item_map(source_root);
 
     check_module_item_map(
         &item_map,
-        module.module_id,
+        module_id,
         "
             Baz: t v
             test_crate: t
@@ -348,11 +350,10 @@ fn reexport_across_crates() {
 
 fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
     let (mut db, pos) = MockDatabase::with_position(initial);
-    let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap();
-    let krate = module.krate(&db).unwrap();
+    let source_root = db.file_source_root(pos.file_id);
     {
         let events = db.log_executed(|| {
-            db.item_map(krate.crate_id);
+            db.item_map(source_root);
         });
         assert!(format!("{:?}", events).contains("item_map"))
     }
@@ -361,7 +362,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) {
 
     {
         let events = db.log_executed(|| {
-            db.item_map(krate.crate_id);
+            db.item_map(source_root);
         });
         assert!(
             !format!("{:?}", events).contains("item_map"),
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_struct.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_struct.snap
index 8747fae181..c4a2d5cf8b 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_struct.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_struct.snap
@@ -1,19 +1,19 @@
 ---
-created: "2019-01-24T14:51:32.808861856+00:00"
-creator: insta@0.5.2
+created: "2019-01-22T14:45:00.058678600+00:00"
+creator: insta@0.4.0
 expression: "&result"
-source: crates/ra_hir/src/ty/tests.rs
+source: "crates\\ra_hir\\src\\ty\\tests.rs"
 ---
 [72; 154) '{     ...a.c; }': ()
 [82; 83) 'c': [unknown]
-[86; 87) 'C': C
+[86; 87) 'C': [unknown]
 [86; 90) 'C(1)': [unknown]
 [88; 89) '1': i32
-[96; 97) 'B': B
+[96; 97) 'B': [unknown]
 [107; 108) 'a': A
 [114; 133) 'A { b:...C(1) }': A
 [121; 122) 'B': B
-[127; 128) 'C': C
+[127; 128) 'C': [unknown]
 [127; 131) 'C(1)': C
 [129; 130) '1': i32
 [139; 140) 'a': A
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
index 890426db77..3267d1ac5a 100644
--- a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
+++ b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap
@@ -1,8 +1,8 @@
 ---
-created: "2019-01-24T08:39:53.759318522+00:00"
-creator: insta@0.5.2
+created: "2019-01-22T14:45:00.975229300+00:00"
+creator: insta@0.4.0
 expression: "&source_change"
-source: crates/ra_ide_api/src/rename.rs
+source: "crates\\ra_ide_api\\src\\rename.rs"
 ---
 Some(
     SourceChange {
@@ -10,7 +10,7 @@ Some(
         source_file_edits: [
             SourceFileEdit {
                 file_id: FileId(
-                    2
+                    1
                 ),
                 edit: TextEdit {
                     atoms: [
@@ -25,7 +25,7 @@ Some(
         file_system_edits: [
             MoveFile {
                 src: FileId(
-                    3
+                    2
                 ),
                 dst_source_root: SourceRootId(
                     0