aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/assist_ctx.rs4
-rw-r--r--crates/ra_assists/src/assists/add_new.rs6
-rw-r--r--crates/ra_hir/src/code_model.rs6
-rw-r--r--crates/ra_hir/src/code_model/src.rs41
-rw-r--r--crates/ra_hir/src/from_source.rs62
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs28
-rw-r--r--crates/ra_hir_def/src/adt.rs8
-rw-r--r--crates/ra_hir_def/src/attr.rs9
-rw-r--r--crates/ra_hir_def/src/body.rs17
-rw-r--r--crates/ra_hir_def/src/body/lower.rs11
-rw-r--r--crates/ra_hir_def/src/body/scope.rs6
-rw-r--r--crates/ra_hir_def/src/data.rs5
-rw-r--r--crates/ra_hir_def/src/diagnostics.rs6
-rw-r--r--crates/ra_hir_def/src/docs.rs6
-rw-r--r--crates/ra_hir_def/src/expr.rs14
-rw-r--r--crates/ra_hir_def/src/generics.rs3
-rw-r--r--crates/ra_hir_def/src/lib.rs60
-rw-r--r--crates/ra_hir_def/src/nameres.rs16
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs6
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs4
-rw-r--r--crates/ra_hir_def/src/path.rs34
-rw-r--r--crates/ra_hir_def/src/src.rs54
-rw-r--r--crates/ra_hir_expand/src/diagnostics.rs4
-rw-r--r--crates/ra_hir_expand/src/lib.rs81
-rw-r--r--crates/ra_hir_expand/src/name.rs6
-rw-r--r--crates/ra_hir_ty/src/db.rs12
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs14
-rw-r--r--crates/ra_hir_ty/src/infer.rs38
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs7
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs39
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs2
-rw-r--r--crates/ra_hir_ty/src/lib.rs15
-rw-r--r--crates/ra_hir_ty/src/lower.rs49
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs9
-rw-r--r--crates/ra_hir_ty/src/tests.rs110
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs15
-rw-r--r--crates/ra_ide/src/call_info.rs2
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs4
-rw-r--r--crates/ra_ide/src/diagnostics.rs2
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs4
-rw-r--r--crates/ra_ide/src/expand.rs8
-rw-r--r--crates/ra_ide/src/expand_macro.rs8
-rw-r--r--crates/ra_ide/src/goto_definition.rs8
-rw-r--r--crates/ra_ide/src/hover.rs2
-rw-r--r--crates/ra_ide/src/impls.rs10
-rw-r--r--crates/ra_ide/src/inlay_hints.rs2
-rw-r--r--crates/ra_ide/src/parent_module.rs4
-rw-r--r--crates/ra_ide/src/references.rs8
-rw-r--r--crates/ra_ide/src/references/classify.rs6
-rw-r--r--crates/ra_ide/src/references/rename.rs54
-rw-r--r--crates/ra_ide/src/runnables.rs6
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs6
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs2
-rw-r--r--crates/ra_tt/src/lib.rs16
55 files changed, 609 insertions, 352 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index 0ea84d548..993aebc47 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -1,5 +1,5 @@
1//! This module defines `AssistCtx` -- the API surface that is exposed to assists. 1//! This module defines `AssistCtx` -- the API surface that is exposed to assists.
2use hir::{db::HirDatabase, SourceAnalyzer}; 2use hir::{db::HirDatabase, InFile, SourceAnalyzer};
3use ra_db::FileRange; 3use ra_db::FileRange;
4use ra_fmt::{leading_indent, reindent}; 4use ra_fmt::{leading_indent, reindent};
5use ra_syntax::{ 5use ra_syntax::{
@@ -117,7 +117,7 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
117 node: &SyntaxNode, 117 node: &SyntaxNode,
118 offset: Option<TextUnit>, 118 offset: Option<TextUnit>,
119 ) -> SourceAnalyzer { 119 ) -> SourceAnalyzer {
120 SourceAnalyzer::new(self.db, hir::Source::new(self.frange.file_id.into(), node), offset) 120 SourceAnalyzer::new(self.db, InFile::new(self.frange.file_id.into(), node), offset)
121 } 121 }
122 122
123 pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { 123 pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement {
diff --git a/crates/ra_assists/src/assists/add_new.rs b/crates/ra_assists/src/assists/add_new.rs
index 8f68bd5fb..f977547fb 100644
--- a/crates/ra_assists/src/assists/add_new.rs
+++ b/crates/ra_assists/src/assists/add_new.rs
@@ -1,5 +1,5 @@
1use format_buf::format; 1use format_buf::format;
2use hir::{db::HirDatabase, FromSource}; 2use hir::{db::HirDatabase, FromSource, InFile};
3use join_to_string::join; 3use join_to_string::join;
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{ 5 ast::{
@@ -141,7 +141,7 @@ fn find_struct_impl(
141 })?; 141 })?;
142 142
143 let struct_ty = { 143 let struct_ty = {
144 let src = hir::Source { file_id: ctx.frange.file_id.into(), value: strukt.clone() }; 144 let src = InFile { file_id: ctx.frange.file_id.into(), value: strukt.clone() };
145 hir::Struct::from_source(db, src).unwrap().ty(db) 145 hir::Struct::from_source(db, src).unwrap().ty(db)
146 }; 146 };
147 147
@@ -152,7 +152,7 @@ fn find_struct_impl(
152 return false; 152 return false;
153 } 153 }
154 154
155 let src = hir::Source { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() }; 155 let src = InFile { file_id: ctx.frange.file_id.into(), value: impl_blk.clone() };
156 let blk = hir::ImplBlock::from_source(db, src).unwrap(); 156 let blk = hir::ImplBlock::from_source(db, src).unwrap();
157 157
158 let same_ty = blk.target_ty(db) == struct_ty; 158 let same_ty = blk.target_ty(db) == struct_ty;
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 38d66c2a7..dddac915b 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -30,7 +30,7 @@ use crate::{
30 db::{DefDatabase, HirDatabase}, 30 db::{DefDatabase, HirDatabase},
31 ty::display::HirFormatter, 31 ty::display::HirFormatter,
32 ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk}, 32 ty::{self, InEnvironment, InferenceResult, TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk},
33 CallableDef, Either, HirDisplay, Name, Source, 33 CallableDef, Either, HirDisplay, InFile, Name,
34}; 34};
35 35
36/// hir::Crate describes a single crate. It's the main interface with which 36/// hir::Crate describes a single crate. It's the main interface with which
@@ -118,7 +118,7 @@ impl ModuleSource {
118 } 118 }
119 } 119 }
120 120
121 pub fn from_child_node(db: &impl DefDatabase, child: Source<&SyntaxNode>) -> ModuleSource { 121 pub fn from_child_node(db: &impl DefDatabase, child: InFile<&SyntaxNode>) -> ModuleSource {
122 if let Some(m) = 122 if let Some(m) =
123 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) 123 child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi())
124 { 124 {
@@ -901,7 +901,7 @@ impl Local {
901 Type { krate, ty: InEnvironment { value: ty, environment } } 901 Type { krate, ty: InEnvironment { value: ty, environment } }
902 } 902 }
903 903
904 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 904 pub fn source(self, db: &impl HirDatabase) -> InFile<Either<ast::BindPat, ast::SelfParam>> {
905 let (_body, source_map) = db.body_with_source_map(self.parent.into()); 905 let (_body, source_map) = db.body_with_source_map(self.parent.into());
906 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 906 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
907 let root = src.file_syntax(db); 907 let root = src.file_syntax(db);
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index bf3ee0834..2cf210349 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -1,6 +1,9 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; 3use hir_def::{
4 src::{HasChildSource, HasSource as _},
5 AstItemDef, Lookup, VariantId,
6};
4use hir_expand::either::Either; 7use hir_expand::either::Either;
5use ra_syntax::ast; 8use ra_syntax::ast;
6 9
@@ -9,18 +12,18 @@ use crate::{
9 Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, 12 Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
10}; 13};
11 14
12pub use hir_expand::Source; 15pub use hir_expand::InFile;
13 16
14pub trait HasSource { 17pub trait HasSource {
15 type Ast; 18 type Ast;
16 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>; 19 fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast>;
17} 20}
18 21
19/// NB: Module is !HasSource, because it has two source nodes at the same time: 22/// NB: Module is !HasSource, because it has two source nodes at the same time:
20/// definition and declaration. 23/// definition and declaration.
21impl Module { 24impl Module {
22 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 25 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
23 pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> { 26 pub fn definition_source(self, db: &impl DefDatabase) -> InFile<ModuleSource> {
24 let def_map = db.crate_def_map(self.id.krate); 27 let def_map = db.crate_def_map(self.id.krate);
25 let src = def_map[self.id.local_id].definition_source(db); 28 let src = def_map[self.id.local_id].definition_source(db);
26 src.map(|it| match it { 29 src.map(|it| match it {
@@ -31,7 +34,7 @@ impl Module {
31 34
32 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 35 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
33 /// `None` for the crate root. 36 /// `None` for the crate root.
34 pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { 37 pub fn declaration_source(self, db: &impl DefDatabase) -> Option<InFile<ast::Module>> {
35 let def_map = db.crate_def_map(self.id.krate); 38 let def_map = db.crate_def_map(self.id.krate);
36 def_map[self.id.local_id].declaration_source(db) 39 def_map[self.id.local_id].declaration_source(db)
37 } 40 }
@@ -39,7 +42,7 @@ impl Module {
39 42
40impl HasSource for StructField { 43impl HasSource for StructField {
41 type Ast = FieldSource; 44 type Ast = FieldSource;
42 fn source(self, db: &impl DefDatabase) -> Source<FieldSource> { 45 fn source(self, db: &impl DefDatabase) -> InFile<FieldSource> {
43 let var = VariantId::from(self.parent); 46 let var = VariantId::from(self.parent);
44 let src = var.child_source(db); 47 let src = var.child_source(db);
45 src.map(|it| match it[self.id].clone() { 48 src.map(|it| match it[self.id].clone() {
@@ -50,67 +53,67 @@ impl HasSource for StructField {
50} 53}
51impl HasSource for Struct { 54impl HasSource for Struct {
52 type Ast = ast::StructDef; 55 type Ast = ast::StructDef;
53 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> { 56 fn source(self, db: &impl DefDatabase) -> InFile<ast::StructDef> {
54 self.id.source(db) 57 self.id.source(db)
55 } 58 }
56} 59}
57impl HasSource for Union { 60impl HasSource for Union {
58 type Ast = ast::UnionDef; 61 type Ast = ast::UnionDef;
59 fn source(self, db: &impl DefDatabase) -> Source<ast::UnionDef> { 62 fn source(self, db: &impl DefDatabase) -> InFile<ast::UnionDef> {
60 self.id.source(db) 63 self.id.source(db)
61 } 64 }
62} 65}
63impl HasSource for Enum { 66impl HasSource for Enum {
64 type Ast = ast::EnumDef; 67 type Ast = ast::EnumDef;
65 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> { 68 fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumDef> {
66 self.id.source(db) 69 self.id.source(db)
67 } 70 }
68} 71}
69impl HasSource for EnumVariant { 72impl HasSource for EnumVariant {
70 type Ast = ast::EnumVariant; 73 type Ast = ast::EnumVariant;
71 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> { 74 fn source(self, db: &impl DefDatabase) -> InFile<ast::EnumVariant> {
72 self.parent.id.child_source(db).map(|map| map[self.id].clone()) 75 self.parent.id.child_source(db).map(|map| map[self.id].clone())
73 } 76 }
74} 77}
75impl HasSource for Function { 78impl HasSource for Function {
76 type Ast = ast::FnDef; 79 type Ast = ast::FnDef;
77 fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> { 80 fn source(self, db: &impl DefDatabase) -> InFile<ast::FnDef> {
78 self.id.lookup(db).source(db) 81 self.id.lookup(db).source(db)
79 } 82 }
80} 83}
81impl HasSource for Const { 84impl HasSource for Const {
82 type Ast = ast::ConstDef; 85 type Ast = ast::ConstDef;
83 fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> { 86 fn source(self, db: &impl DefDatabase) -> InFile<ast::ConstDef> {
84 self.id.lookup(db).source(db) 87 self.id.lookup(db).source(db)
85 } 88 }
86} 89}
87impl HasSource for Static { 90impl HasSource for Static {
88 type Ast = ast::StaticDef; 91 type Ast = ast::StaticDef;
89 fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> { 92 fn source(self, db: &impl DefDatabase) -> InFile<ast::StaticDef> {
90 self.id.lookup(db).source(db) 93 self.id.lookup(db).source(db)
91 } 94 }
92} 95}
93impl HasSource for Trait { 96impl HasSource for Trait {
94 type Ast = ast::TraitDef; 97 type Ast = ast::TraitDef;
95 fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> { 98 fn source(self, db: &impl DefDatabase) -> InFile<ast::TraitDef> {
96 self.id.source(db) 99 self.id.source(db)
97 } 100 }
98} 101}
99impl HasSource for TypeAlias { 102impl HasSource for TypeAlias {
100 type Ast = ast::TypeAliasDef; 103 type Ast = ast::TypeAliasDef;
101 fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> { 104 fn source(self, db: &impl DefDatabase) -> InFile<ast::TypeAliasDef> {
102 self.id.lookup(db).source(db) 105 self.id.lookup(db).source(db)
103 } 106 }
104} 107}
105impl HasSource for MacroDef { 108impl HasSource for MacroDef {
106 type Ast = ast::MacroCall; 109 type Ast = ast::MacroCall;
107 fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> { 110 fn source(self, db: &impl DefDatabase) -> InFile<ast::MacroCall> {
108 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } 111 InFile { file_id: self.id.ast_id.file_id, value: self.id.ast_id.to_node(db) }
109 } 112 }
110} 113}
111impl HasSource for ImplBlock { 114impl HasSource for ImplBlock {
112 type Ast = ast::ImplBlock; 115 type Ast = ast::ImplBlock;
113 fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> { 116 fn source(self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> {
114 self.id.source(db) 117 self.id.source(db)
115 } 118 }
116} 119}
@@ -118,7 +121,7 @@ impl HasSource for Import {
118 type Ast = Either<ast::UseTree, ast::ExternCrateItem>; 121 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
119 122
120 /// Returns the syntax of the last path segment corresponding to this import 123 /// Returns the syntax of the last path segment corresponding to this import
121 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> { 124 fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> {
122 let src = self.parent.definition_source(db); 125 let src = self.parent.definition_source(db);
123 let (_, source_map) = db.raw_items_with_source_map(src.file_id); 126 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
124 let root = db.parse_or_expand(src.file_id).unwrap(); 127 let root = db.parse_or_expand(src.file_id).unwrap();
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 9f7c22b21..82bf641dc 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -10,46 +10,46 @@ use ra_syntax::{
10use crate::{ 10use crate::{
11 db::{AstDatabase, DefDatabase, HirDatabase}, 11 db::{AstDatabase, DefDatabase, HirDatabase},
12 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, 12 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock,
13 Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait, 13 InFile, Local, MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait,
14 TypeAlias, Union, VariantDef, 14 TypeAlias, Union, VariantDef,
15}; 15};
16 16
17pub trait FromSource: Sized { 17pub trait FromSource: Sized {
18 type Ast; 18 type Ast;
19 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>; 19 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>;
20} 20}
21 21
22impl FromSource for Struct { 22impl FromSource for Struct {
23 type Ast = ast::StructDef; 23 type Ast = ast::StructDef;
24 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 24 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
25 let id = from_source(db, src)?; 25 let id = from_source(db, src)?;
26 Some(Struct { id }) 26 Some(Struct { id })
27 } 27 }
28} 28}
29impl FromSource for Union { 29impl FromSource for Union {
30 type Ast = ast::UnionDef; 30 type Ast = ast::UnionDef;
31 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 31 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
32 let id = from_source(db, src)?; 32 let id = from_source(db, src)?;
33 Some(Union { id }) 33 Some(Union { id })
34 } 34 }
35} 35}
36impl FromSource for Enum { 36impl FromSource for Enum {
37 type Ast = ast::EnumDef; 37 type Ast = ast::EnumDef;
38 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 38 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
39 let id = from_source(db, src)?; 39 let id = from_source(db, src)?;
40 Some(Enum { id }) 40 Some(Enum { id })
41 } 41 }
42} 42}
43impl FromSource for Trait { 43impl FromSource for Trait {
44 type Ast = ast::TraitDef; 44 type Ast = ast::TraitDef;
45 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 45 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
46 let id = from_source(db, src)?; 46 let id = from_source(db, src)?;
47 Some(Trait { id }) 47 Some(Trait { id })
48 } 48 }
49} 49}
50impl FromSource for Function { 50impl FromSource for Function {
51 type Ast = ast::FnDef; 51 type Ast = ast::FnDef;
52 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 52 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
53 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { 53 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
54 Container::Trait(it) => it.items(db), 54 Container::Trait(it) => it.items(db),
55 Container::ImplBlock(it) => it.items(db), 55 Container::ImplBlock(it) => it.items(db),
@@ -76,7 +76,7 @@ impl FromSource for Function {
76 76
77impl FromSource for Const { 77impl FromSource for Const {
78 type Ast = ast::ConstDef; 78 type Ast = ast::ConstDef;
79 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 79 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
80 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { 80 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
81 Container::Trait(it) => it.items(db), 81 Container::Trait(it) => it.items(db),
82 Container::ImplBlock(it) => it.items(db), 82 Container::ImplBlock(it) => it.items(db),
@@ -102,7 +102,7 @@ impl FromSource for Const {
102} 102}
103impl FromSource for Static { 103impl FromSource for Static {
104 type Ast = ast::StaticDef; 104 type Ast = ast::StaticDef;
105 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 105 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
106 let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { 106 let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
107 Container::Module(it) => it, 107 Container::Module(it) => it,
108 Container::Trait(_) | Container::ImplBlock(_) => return None, 108 Container::Trait(_) | Container::ImplBlock(_) => return None,
@@ -120,7 +120,7 @@ impl FromSource for Static {
120 120
121impl FromSource for TypeAlias { 121impl FromSource for TypeAlias {
122 type Ast = ast::TypeAliasDef; 122 type Ast = ast::TypeAliasDef;
123 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 123 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
124 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { 124 let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? {
125 Container::Trait(it) => it.items(db), 125 Container::Trait(it) => it.items(db),
126 Container::ImplBlock(it) => it.items(db), 126 Container::ImplBlock(it) => it.items(db),
@@ -147,11 +147,11 @@ impl FromSource for TypeAlias {
147 147
148impl FromSource for MacroDef { 148impl FromSource for MacroDef {
149 type Ast = ast::MacroCall; 149 type Ast = ast::MacroCall;
150 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 150 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
151 let kind = MacroDefKind::Declarative; 151 let kind = MacroDefKind::Declarative;
152 152
153 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 153 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
154 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; 154 let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?;
155 let krate = module.krate().crate_id(); 155 let krate = module.krate().crate_id();
156 156
157 let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value)); 157 let ast_id = AstId::new(src.file_id, db.ast_id_map(src.file_id).ast_id(&src.value));
@@ -163,7 +163,7 @@ impl FromSource for MacroDef {
163 163
164impl FromSource for ImplBlock { 164impl FromSource for ImplBlock {
165 type Ast = ast::ImplBlock; 165 type Ast = ast::ImplBlock;
166 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 166 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
167 let id = from_source(db, src)?; 167 let id = from_source(db, src)?;
168 Some(ImplBlock { id }) 168 Some(ImplBlock { id })
169 } 169 }
@@ -171,9 +171,9 @@ impl FromSource for ImplBlock {
171 171
172impl FromSource for EnumVariant { 172impl FromSource for EnumVariant {
173 type Ast = ast::EnumVariant; 173 type Ast = ast::EnumVariant;
174 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 174 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
175 let parent_enum = src.value.parent_enum(); 175 let parent_enum = src.value.parent_enum();
176 let src_enum = Source { file_id: src.file_id, value: parent_enum }; 176 let src_enum = InFile { file_id: src.file_id, value: parent_enum };
177 let variants = Enum::from_source(db, src_enum)?.variants(db); 177 let variants = Enum::from_source(db, src_enum)?.variants(db);
178 variants.into_iter().find(|v| same_source(&v.source(db), &src)) 178 variants.into_iter().find(|v| same_source(&v.source(db), &src))
179 } 179 }
@@ -181,17 +181,17 @@ impl FromSource for EnumVariant {
181 181
182impl FromSource for StructField { 182impl FromSource for StructField {
183 type Ast = FieldSource; 183 type Ast = FieldSource;
184 fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { 184 fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> {
185 let variant_def: VariantDef = match src.value { 185 let variant_def: VariantDef = match src.value {
186 FieldSource::Named(ref field) => { 186 FieldSource::Named(ref field) => {
187 let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?; 187 let value = field.syntax().ancestors().find_map(ast::StructDef::cast)?;
188 let src = Source { file_id: src.file_id, value }; 188 let src = InFile { file_id: src.file_id, value };
189 let def = Struct::from_source(db, src)?; 189 let def = Struct::from_source(db, src)?;
190 VariantDef::from(def) 190 VariantDef::from(def)
191 } 191 }
192 FieldSource::Pos(ref field) => { 192 FieldSource::Pos(ref field) => {
193 let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?; 193 let value = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?;
194 let src = Source { file_id: src.file_id, value }; 194 let src = InFile { file_id: src.file_id, value };
195 let def = EnumVariant::from_source(db, src)?; 195 let def = EnumVariant::from_source(db, src)?;
196 VariantDef::from(def) 196 VariantDef::from(def)
197 } 197 }
@@ -206,14 +206,14 @@ impl FromSource for StructField {
206} 206}
207 207
208impl Local { 208impl Local {
209 pub fn from_source(db: &impl HirDatabase, src: Source<ast::BindPat>) -> Option<Self> { 209 pub fn from_source(db: &impl HirDatabase, src: InFile<ast::BindPat>) -> Option<Self> {
210 let file_id = src.file_id; 210 let file_id = src.file_id;
211 let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| { 211 let parent: DefWithBody = src.value.syntax().ancestors().find_map(|it| {
212 let res = match_ast! { 212 let res = match_ast! {
213 match it { 213 match it {
214 ast::ConstDef(value) => { Const::from_source(db, Source { value, file_id})?.into() }, 214 ast::ConstDef(value) => { Const::from_source(db, InFile { value, file_id})?.into() },
215 ast::StaticDef(value) => { Static::from_source(db, Source { value, file_id})?.into() }, 215 ast::StaticDef(value) => { Static::from_source(db, InFile { value, file_id})?.into() },
216 ast::FnDef(value) => { Function::from_source(db, Source { value, file_id})?.into() }, 216 ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.into() },
217 _ => return None, 217 _ => return None,
218 } 218 }
219 }; 219 };
@@ -227,16 +227,16 @@ impl Local {
227} 227}
228 228
229impl Module { 229impl Module {
230 pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { 230 pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> {
231 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); 231 let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast);
232 232
233 let parent_module = match parent_declaration { 233 let parent_module = match parent_declaration {
234 Some(parent_declaration) => { 234 Some(parent_declaration) => {
235 let src_parent = Source { file_id: src.file_id, value: parent_declaration }; 235 let src_parent = InFile { file_id: src.file_id, value: parent_declaration };
236 Module::from_declaration(db, src_parent) 236 Module::from_declaration(db, src_parent)
237 } 237 }
238 _ => { 238 _ => {
239 let src_parent = Source { 239 let src_parent = InFile {
240 file_id: src.file_id, 240 file_id: src.file_id,
241 value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), 241 value: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
242 }; 242 };
@@ -248,13 +248,13 @@ impl Module {
248 parent_module.child(db, &child_name.as_name()) 248 parent_module.child(db, &child_name.as_name())
249 } 249 }
250 250
251 pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { 251 pub fn from_definition(db: &impl DefDatabase, src: InFile<ModuleSource>) -> Option<Self> {
252 match src.value { 252 match src.value {
253 ModuleSource::Module(ref module) => { 253 ModuleSource::Module(ref module) => {
254 assert!(!module.has_semi()); 254 assert!(!module.has_semi());
255 return Module::from_declaration( 255 return Module::from_declaration(
256 db, 256 db,
257 Source { file_id: src.file_id, value: module.clone() }, 257 InFile { file_id: src.file_id, value: module.clone() },
258 ); 258 );
259 } 259 }
260 ModuleSource::SourceFile(_) => (), 260 ModuleSource::SourceFile(_) => (),
@@ -271,13 +271,13 @@ impl Module {
271 } 271 }
272} 272}
273 273
274fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: Source<N>) -> Option<DEF> 274fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: InFile<N>) -> Option<DEF>
275where 275where
276 N: AstNode, 276 N: AstNode,
277 DEF: AstItemDef<N>, 277 DEF: AstItemDef<N>,
278{ 278{
279 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 279 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
280 let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; 280 let module = Module::from_definition(db, InFile::new(src.file_id, module_src))?;
281 let ctx = LocationCtx::new(db, module.id, src.file_id); 281 let ctx = LocationCtx::new(db, module.id, src.file_id);
282 let items = db.ast_id_map(src.file_id); 282 let items = db.ast_id_map(src.file_id);
283 let item_id = items.ast_id(&src.value); 283 let item_id = items.ast_id(&src.value);
@@ -291,7 +291,7 @@ enum Container {
291} 291}
292 292
293impl Container { 293impl Container {
294 fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option<Container> { 294 fn find(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<Container> {
295 // FIXME: this doesn't try to handle nested declarations 295 // FIXME: this doesn't try to handle nested declarations
296 for container in src.value.ancestors() { 296 for container in src.value.ancestors() {
297 let res = match_ast! { 297 let res = match_ast! {
@@ -322,6 +322,6 @@ impl Container {
322/// In general, we do not guarantee that we have exactly one instance of a 322/// In general, we do not guarantee that we have exactly one instance of a
323/// syntax tree for each file. We probably should add such guarantee, but, for 323/// syntax tree for each file. We probably should add such guarantee, but, for
324/// the time being, we will use identity-less AstPtr comparison. 324/// the time being, we will use identity-less AstPtr comparison.
325fn same_source<N: AstNode>(s1: &Source<N>, s2: &Source<N>) -> bool { 325fn same_source<N: AstNode>(s1: &InFile<N>, s2: &InFile<N>) -> bool {
326 s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) 326 s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new)
327} 327}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 3c12c61f0..88d2f6e02 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -63,5 +63,5 @@ pub use hir_def::{
63 type_ref::Mutability, 63 type_ref::Mutability,
64}; 64};
65pub use hir_expand::{ 65pub use hir_expand::{
66 either::Either, name::Name, HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Source, 66 either::Either, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile,
67}; 67};
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 76c493f1a..1661d92a2 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -18,7 +18,7 @@ use hir_def::{
18 AssocItemId, DefWithBodyId, 18 AssocItemId, DefWithBodyId,
19}; 19};
20use hir_expand::{ 20use hir_expand::{
21 hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroFileKind, Source, 21 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroFileKind,
22}; 22};
23use ra_syntax::{ 23use ra_syntax::{
24 ast::{self, AstNode}, 24 ast::{self, AstNode},
@@ -37,7 +37,7 @@ use crate::{
37 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, 37 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias,
38}; 38};
39 39
40fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 40fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
41 match_ast! { 41 match_ast! {
42 match (node.value) { 42 match (node.value) {
43 ast::Module(it) => { 43 ast::Module(it) => {
@@ -71,7 +71,7 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -
71 71
72fn def_with_body_from_child_node( 72fn def_with_body_from_child_node(
73 db: &impl HirDatabase, 73 db: &impl HirDatabase,
74 child: Source<&SyntaxNode>, 74 child: InFile<&SyntaxNode>,
75) -> Option<DefWithBody> { 75) -> Option<DefWithBody> {
76 child.value.ancestors().find_map(|node| { 76 child.value.ancestors().find_map(|node| {
77 match_ast! { 77 match_ast! {
@@ -141,8 +141,8 @@ impl Expansion {
141 pub fn map_token_down( 141 pub fn map_token_down(
142 &self, 142 &self,
143 db: &impl HirDatabase, 143 db: &impl HirDatabase,
144 token: Source<&SyntaxToken>, 144 token: InFile<&SyntaxToken>,
145 ) -> Option<Source<SyntaxToken>> { 145 ) -> Option<InFile<SyntaxToken>> {
146 let exp_info = self.file_id().expansion_info(db)?; 146 let exp_info = self.file_id().expansion_info(db)?;
147 exp_info.map_token_down(token) 147 exp_info.map_token_down(token)
148 } 148 }
@@ -155,7 +155,7 @@ impl Expansion {
155impl SourceAnalyzer { 155impl SourceAnalyzer {
156 pub fn new( 156 pub fn new(
157 db: &impl HirDatabase, 157 db: &impl HirDatabase,
158 node: Source<&SyntaxNode>, 158 node: InFile<&SyntaxNode>,
159 offset: Option<TextUnit>, 159 offset: Option<TextUnit>,
160 ) -> SourceAnalyzer { 160 ) -> SourceAnalyzer {
161 let def_with_body = def_with_body_from_child_node(db, node); 161 let def_with_body = def_with_body_from_child_node(db, node);
@@ -192,12 +192,12 @@ impl SourceAnalyzer {
192 } 192 }
193 193
194 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> { 194 fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> {
195 let src = Source { file_id: self.file_id, value: expr }; 195 let src = InFile { file_id: self.file_id, value: expr };
196 self.body_source_map.as_ref()?.node_expr(src) 196 self.body_source_map.as_ref()?.node_expr(src)
197 } 197 }
198 198
199 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> { 199 fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
200 let src = Source { file_id: self.file_id, value: pat }; 200 let src = InFile { file_id: self.file_id, value: pat };
201 self.body_source_map.as_ref()?.node_pat(src) 201 self.body_source_map.as_ref()?.node_pat(src)
202 } 202 }
203 203
@@ -243,7 +243,7 @@ impl SourceAnalyzer {
243 pub fn resolve_macro_call( 243 pub fn resolve_macro_call(
244 &self, 244 &self,
245 db: &impl HirDatabase, 245 db: &impl HirDatabase,
246 macro_call: Source<&ast::MacroCall>, 246 macro_call: InFile<&ast::MacroCall>,
247 ) -> Option<MacroDef> { 247 ) -> Option<MacroDef> {
248 let hygiene = Hygiene::new(db, macro_call.file_id); 248 let hygiene = Hygiene::new(db, macro_call.file_id);
249 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; 249 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?;
@@ -318,7 +318,7 @@ impl SourceAnalyzer {
318 let name = name_ref.as_name(); 318 let name = name_ref.as_name();
319 let source_map = self.body_source_map.as_ref()?; 319 let source_map = self.body_source_map.as_ref()?;
320 let scopes = self.scopes.as_ref()?; 320 let scopes = self.scopes.as_ref()?;
321 let scope = scope_for(scopes, source_map, Source::new(self.file_id, name_ref.syntax()))?; 321 let scope = scope_for(scopes, source_map, InFile::new(self.file_id, name_ref.syntax()))?;
322 let entry = scopes.resolve_name_in_scope(scope, &name)?; 322 let entry = scopes.resolve_name_in_scope(scope, &name)?;
323 Some(ScopeEntryWithSyntax { 323 Some(ScopeEntryWithSyntax {
324 name: entry.name().clone(), 324 name: entry.name().clone(),
@@ -446,7 +446,7 @@ impl SourceAnalyzer {
446 pub fn expand( 446 pub fn expand(
447 &self, 447 &self,
448 db: &impl HirDatabase, 448 db: &impl HirDatabase,
449 macro_call: Source<&ast::MacroCall>, 449 macro_call: InFile<&ast::MacroCall>,
450 ) -> Option<Expansion> { 450 ) -> Option<Expansion> {
451 let def = self.resolve_macro_call(db, macro_call)?.id; 451 let def = self.resolve_macro_call(db, macro_call)?.id;
452 let ast_id = AstId::new( 452 let ast_id = AstId::new(
@@ -463,19 +463,19 @@ impl SourceAnalyzer {
463fn scope_for( 463fn scope_for(
464 scopes: &ExprScopes, 464 scopes: &ExprScopes,
465 source_map: &BodySourceMap, 465 source_map: &BodySourceMap,
466 node: Source<&SyntaxNode>, 466 node: InFile<&SyntaxNode>,
467) -> Option<ScopeId> { 467) -> Option<ScopeId> {
468 node.value 468 node.value
469 .ancestors() 469 .ancestors()
470 .filter_map(ast::Expr::cast) 470 .filter_map(ast::Expr::cast)
471 .filter_map(|it| source_map.node_expr(Source::new(node.file_id, &it))) 471 .filter_map(|it| source_map.node_expr(InFile::new(node.file_id, &it)))
472 .find_map(|it| scopes.scope_for(it)) 472 .find_map(|it| scopes.scope_for(it))
473} 473}
474 474
475fn scope_for_offset( 475fn scope_for_offset(
476 scopes: &ExprScopes, 476 scopes: &ExprScopes,
477 source_map: &BodySourceMap, 477 source_map: &BodySourceMap,
478 offset: Source<TextUnit>, 478 offset: InFile<TextUnit>,
479) -> Option<ScopeId> { 479) -> Option<ScopeId> {
480 scopes 480 scopes
481 .scope_by_expr() 481 .scope_by_expr()
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 3666529b0..9ab829aab 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -5,13 +5,13 @@ use std::sync::Arc;
5use hir_expand::{ 5use hir_expand::{
6 either::Either, 6 either::Either,
7 name::{AsName, Name}, 7 name::{AsName, Name},
8 Source, 8 InFile,
9}; 9};
10use ra_arena::{map::ArenaMap, Arena}; 10use ra_arena::{map::ArenaMap, Arena};
11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
12 12
13use crate::{ 13use crate::{
14 db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, 14 db::DefDatabase, src::HasChildSource, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId,
15 LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, 15 LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId,
16}; 16};
17 17
@@ -88,7 +88,7 @@ impl EnumData {
88impl HasChildSource for EnumId { 88impl HasChildSource for EnumId {
89 type ChildId = LocalEnumVariantId; 89 type ChildId = LocalEnumVariantId;
90 type Value = ast::EnumVariant; 90 type Value = ast::EnumVariant;
91 fn child_source(&self, db: &impl DefDatabase) -> Source<ArenaMap<Self::ChildId, Self::Value>> { 91 fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> {
92 let src = self.source(db); 92 let src = self.source(db);
93 let mut trace = Trace::new_for_map(); 93 let mut trace = Trace::new_for_map();
94 lower_enum(&mut trace, &src.value); 94 lower_enum(&mut trace, &src.value);
@@ -145,7 +145,7 @@ impl HasChildSource for VariantId {
145 type ChildId = LocalStructFieldId; 145 type ChildId = LocalStructFieldId;
146 type Value = Either<ast::TupleFieldDef, ast::RecordFieldDef>; 146 type Value = Either<ast::TupleFieldDef, ast::RecordFieldDef>;
147 147
148 fn child_source(&self, db: &impl DefDatabase) -> Source<ArenaMap<Self::ChildId, Self::Value>> { 148 fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> {
149 let src = match self { 149 let src = match self {
150 VariantId::EnumVariantId(it) => { 150 VariantId::EnumVariantId(it) => {
151 // I don't really like the fact that we call into parent source 151 // I don't really like the fact that we call into parent source
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index fffb22201..bc7ade921 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -2,7 +2,7 @@
2 2
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; 5use hir_expand::{either::Either, hygiene::Hygiene, AstId, InFile};
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_syntax::{ 7use ra_syntax::{
8 ast::{self, AstNode, AttrsOwner}, 8 ast::{self, AstNode, AttrsOwner},
@@ -11,7 +11,8 @@ use ra_syntax::{
11use tt::Subtree; 11use tt::Subtree;
12 12
13use crate::{ 13use crate::{
14 db::DefDatabase, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup, 14 db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AstItemDef, AttrDefId,
15 Lookup,
15}; 16};
16 17
17#[derive(Default, Debug, Clone, PartialEq, Eq)] 18#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -68,7 +69,7 @@ impl Attrs {
68 } 69 }
69 } 70 }
70 71
71 fn from_attrs_owner(db: &impl DefDatabase, owner: Source<&dyn AttrsOwner>) -> Attrs { 72 fn from_attrs_owner(db: &impl DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs {
72 let hygiene = Hygiene::new(db, owner.file_id); 73 let hygiene = Hygiene::new(db, owner.file_id);
73 Attrs::new(owner.value, &hygiene) 74 Attrs::new(owner.value, &hygiene)
74 } 75 }
@@ -157,7 +158,7 @@ where
157 N: ast::AttrsOwner, 158 N: ast::AttrsOwner,
158 D: DefDatabase, 159 D: DefDatabase,
159{ 160{
160 let src = Source::new(src.file_id(), src.to_node(db)); 161 let src = InFile::new(src.file_id, src.to_node(db));
161 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) 162 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
162} 163}
163 164
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index a57a0176d..69508dd8a 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -6,7 +6,7 @@ pub mod scope;
6use std::{ops::Index, sync::Arc}; 6use std::{ops::Index, sync::Arc};
7 7
8use hir_expand::{ 8use hir_expand::{
9 either::Either, hygiene::Hygiene, AstId, HirFileId, MacroDefId, MacroFileKind, Source, 9 either::Either, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId, MacroFileKind,
10}; 10};
11use ra_arena::{map::ArenaMap, Arena}; 11use ra_arena::{map::ArenaMap, Arena};
12use ra_syntax::{ast, AstNode, AstPtr}; 12use ra_syntax::{ast, AstNode, AstPtr};
@@ -17,7 +17,8 @@ use crate::{
17 expr::{Expr, ExprId, Pat, PatId}, 17 expr::{Expr, ExprId, Pat, PatId},
18 nameres::CrateDefMap, 18 nameres::CrateDefMap,
19 path::Path, 19 path::Path,
20 DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, 20 src::HasSource,
21 DefWithBodyId, HasModule, Lookup, ModuleId,
21}; 22};
22 23
23struct Expander { 24struct Expander {
@@ -73,8 +74,8 @@ impl Expander {
73 std::mem::forget(mark); 74 std::mem::forget(mark);
74 } 75 }
75 76
76 fn to_source<T>(&self, value: T) -> Source<T> { 77 fn to_source<T>(&self, value: T) -> InFile<T> {
77 Source { file_id: self.current_file_id, value } 78 InFile { file_id: self.current_file_id, value }
78 } 79 }
79 80
80 fn parse_path(&mut self, path: ast::Path) -> Option<Path> { 81 fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
@@ -115,10 +116,10 @@ pub struct Body {
115} 116}
116 117
117pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 118pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
118pub type ExprSource = Source<ExprPtr>; 119pub type ExprSource = InFile<ExprPtr>;
119 120
120pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; 121pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
121pub type PatSource = Source<PatPtr>; 122pub type PatSource = InFile<PatPtr>;
122 123
123/// An item body together with the mapping from syntax nodes to HIR expression 124/// An item body together with the mapping from syntax nodes to HIR expression
124/// IDs. This is needed to go from e.g. a position in a file to the HIR 125/// IDs. This is needed to go from e.g. a position in a file to the HIR
@@ -205,7 +206,7 @@ impl BodySourceMap {
205 self.expr_map_back.get(expr).copied() 206 self.expr_map_back.get(expr).copied()
206 } 207 }
207 208
208 pub fn node_expr(&self, node: Source<&ast::Expr>) -> Option<ExprId> { 209 pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
209 let src = node.map(|it| Either::A(AstPtr::new(it))); 210 let src = node.map(|it| Either::A(AstPtr::new(it)));
210 self.expr_map.get(&src).cloned() 211 self.expr_map.get(&src).cloned()
211 } 212 }
@@ -214,7 +215,7 @@ impl BodySourceMap {
214 self.pat_map_back.get(pat).copied() 215 self.pat_map_back.get(pat).copied()
215 } 216 }
216 217
217 pub fn node_pat(&self, node: Source<&ast::Pat>) -> Option<PatId> { 218 pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
218 let src = node.map(|it| Either::A(AstPtr::new(it))); 219 let src = node.map(|it| Either::A(AstPtr::new(it)));
219 self.pat_map.get(&src).cloned() 220 self.pat_map.get(&src).cloned()
220 } 221 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 331736cb2..be1eaa523 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -429,10 +429,19 @@ where
429 let index = self.collect_expr_opt(e.index()); 429 let index = self.collect_expr_opt(e.index());
430 self.alloc_expr(Expr::Index { base, index }, syntax_ptr) 430 self.alloc_expr(Expr::Index { base, index }, syntax_ptr)
431 } 431 }
432 ast::Expr::RangeExpr(e) => {
433 let lhs = e.start().map(|lhs| self.collect_expr(lhs));
434 let rhs = e.end().map(|rhs| self.collect_expr(rhs));
435 match e.op_kind() {
436 Some(range_type) => {
437 self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr)
438 }
439 None => self.alloc_expr(Expr::Missing, syntax_ptr),
440 }
441 }
432 442
433 // FIXME implement HIR for these: 443 // FIXME implement HIR for these:
434 ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 444 ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
435 ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
436 ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { 445 ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) {
437 Some((mark, expansion)) => { 446 Some((mark, expansion)) => {
438 let id = self.collect_expr(expansion); 447 let id = self.collect_expr(expansion);
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 625aa39dd..ab6599b23 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -171,7 +171,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
171 171
172#[cfg(test)] 172#[cfg(test)]
173mod tests { 173mod tests {
174 use hir_expand::{name::AsName, Source}; 174 use hir_expand::{name::AsName, InFile};
175 use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; 175 use ra_db::{fixture::WithFixture, FileId, SourceDatabase};
176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 176 use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
177 use test_utils::{assert_eq_text, covers, extract_offset}; 177 use test_utils::{assert_eq_text, covers, extract_offset};
@@ -211,7 +211,7 @@ mod tests {
211 let (_body, source_map) = db.body_with_source_map(function.into()); 211 let (_body, source_map) = db.body_with_source_map(function.into());
212 212
213 let expr_id = source_map 213 let expr_id = source_map
214 .node_expr(Source { file_id: file_id.into(), value: &marker.into() }) 214 .node_expr(InFile { file_id: file_id.into(), value: &marker.into() })
215 .unwrap(); 215 .unwrap();
216 let scope = scopes.scope_for(expr_id); 216 let scope = scopes.scope_for(expr_id);
217 217
@@ -318,7 +318,7 @@ mod tests {
318 let expr_scope = { 318 let expr_scope = {
319 let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); 319 let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
320 let expr_id = 320 let expr_id =
321 source_map.node_expr(Source { file_id: file_id.into(), value: &expr_ast }).unwrap(); 321 source_map.node_expr(InFile { file_id: file_id.into(), value: &expr_ast }).unwrap();
322 scopes.scope_for(expr_id).unwrap() 322 scopes.scope_for(expr_id).unwrap()
323 }; 323 };
324 324
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index fee10b237..095d7064a 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -10,9 +10,10 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::HasSource,
13 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
14 AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource, 15 AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId,
15 ImplId, Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
16}; 17};
17 18
18#[derive(Debug, Clone, PartialEq, Eq)] 19#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs
index eda9b2269..095498429 100644
--- a/crates/ra_hir_def/src/diagnostics.rs
+++ b/crates/ra_hir_def/src/diagnostics.rs
@@ -6,7 +6,7 @@ use hir_expand::diagnostics::Diagnostic;
6use ra_db::RelativePathBuf; 6use ra_db::RelativePathBuf;
7use ra_syntax::{ast, AstPtr, SyntaxNodePtr}; 7use ra_syntax::{ast, AstPtr, SyntaxNodePtr};
8 8
9use hir_expand::{HirFileId, Source}; 9use hir_expand::{HirFileId, InFile};
10 10
11#[derive(Debug)] 11#[derive(Debug)]
12pub struct UnresolvedModule { 12pub struct UnresolvedModule {
@@ -19,8 +19,8 @@ impl Diagnostic for UnresolvedModule {
19 fn message(&self) -> String { 19 fn message(&self) -> String {
20 "unresolved module".to_string() 20 "unresolved module".to_string()
21 } 21 }
22 fn source(&self) -> Source<SyntaxNodePtr> { 22 fn source(&self) -> InFile<SyntaxNodePtr> {
23 Source { file_id: self.file, value: self.decl.into() } 23 InFile { file_id: self.file, value: self.decl.into() }
24 } 24 }
25 fn as_any(&self) -> &(dyn Any + Send + 'static) { 25 fn as_any(&self) -> &(dyn Any + Send + 'static) {
26 self 26 self
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs
index 34ed9b7a5..ec944373d 100644
--- a/crates/ra_hir_def/src/docs.rs
+++ b/crates/ra_hir_def/src/docs.rs
@@ -8,7 +8,11 @@ use std::sync::Arc;
8use hir_expand::either::Either; 8use hir_expand::either::Either;
9use ra_syntax::ast; 9use ra_syntax::ast;
10 10
11use crate::{db::DefDatabase, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup}; 11use crate::{
12 db::DefDatabase,
13 src::{HasChildSource, HasSource},
14 AdtId, AstItemDef, AttrDefId, Lookup,
15};
12 16
13/// Holds documentation 17/// Holds documentation
14#[derive(Debug, Clone, PartialEq, Eq)] 18#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index 04c1d8f69..6fad80a8d 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -14,6 +14,7 @@
14 14
15use hir_expand::name::Name; 15use hir_expand::name::Name;
16use ra_arena::{impl_arena_id, RawId}; 16use ra_arena::{impl_arena_id, RawId};
17use ra_syntax::ast::RangeOp;
17 18
18use crate::{ 19use crate::{
19 builtin_type::{BuiltinFloat, BuiltinInt}, 20 builtin_type::{BuiltinFloat, BuiltinInt},
@@ -130,6 +131,11 @@ pub enum Expr {
130 rhs: ExprId, 131 rhs: ExprId,
131 op: Option<BinaryOp>, 132 op: Option<BinaryOp>,
132 }, 133 },
134 Range {
135 lhs: Option<ExprId>,
136 rhs: Option<ExprId>,
137 range_type: RangeOp,
138 },
133 Index { 139 Index {
134 base: ExprId, 140 base: ExprId,
135 index: ExprId, 141 index: ExprId,
@@ -288,6 +294,14 @@ impl Expr {
288 f(*lhs); 294 f(*lhs);
289 f(*rhs); 295 f(*rhs);
290 } 296 }
297 Expr::Range { lhs, rhs, .. } => {
298 if let Some(lhs) = rhs {
299 f(*lhs);
300 }
301 if let Some(rhs) = lhs {
302 f(*rhs);
303 }
304 }
291 Expr::Index { base, index } => { 305 Expr::Index { base, index } => {
292 f(*base); 306 f(*base);
293 f(*index); 307 f(*index);
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 3f94e40e4..5f648ffc3 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -9,8 +9,9 @@ use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, 11 db::DefDatabase,
12 src::HasSource,
12 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TypeBound, TypeRef},
13 AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup, 14 AdtId, AstItemDef, ContainerId, GenericDefId, Lookup,
14}; 15};
15 16
16/// Data about a generic parameter (to a function, struct, impl, ...). 17/// Data about a generic parameter (to a function, struct, impl, ...).
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index bc5530896..cfeacfded 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -29,6 +29,8 @@ pub mod resolver;
29mod trace; 29mod trace;
30pub mod nameres; 30pub mod nameres;
31 31
32pub mod src;
33
32#[cfg(test)] 34#[cfg(test)]
33mod test_db; 35mod test_db;
34#[cfg(test)] 36#[cfg(test)]
@@ -36,8 +38,8 @@ mod marks;
36 38
37use std::hash::{Hash, Hasher}; 39use std::hash::{Hash, Hasher};
38 40
39use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; 41use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, InFile, MacroDefId};
40use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; 42use ra_arena::{impl_arena_id, RawId};
41use ra_db::{impl_intern_key, salsa, CrateId}; 43use ra_db::{impl_intern_key, salsa, CrateId};
42use ra_syntax::{ast, AstNode}; 44use ra_syntax::{ast, AstNode};
43 45
@@ -105,10 +107,10 @@ pub trait AstItemDef<N: AstNode>: salsa::InternKey + Clone {
105 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) }; 107 let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) };
106 Self::intern(ctx.db, loc) 108 Self::intern(ctx.db, loc)
107 } 109 }
108 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source<N> { 110 fn source(self, db: &(impl AstDatabase + InternDatabase)) -> InFile<N> {
109 let loc = self.lookup_intern(db); 111 let loc = self.lookup_intern(db);
110 let value = loc.ast_id.to_node(db); 112 let value = loc.ast_id.to_node(db);
111 Source { file_id: loc.ast_id.file_id(), value } 113 InFile { file_id: loc.ast_id.file_id, value }
112 } 114 }
113 fn module(self, db: &impl InternDatabase) -> ModuleId { 115 fn module(self, db: &impl InternDatabase) -> ModuleId {
114 let loc = self.lookup_intern(db); 116 let loc = self.lookup_intern(db);
@@ -514,53 +516,3 @@ impl HasModule for StaticLoc {
514 self.container 516 self.container
515 } 517 }
516} 518}
517
518pub trait HasSource {
519 type Value;
520 fn source(&self, db: &impl db::DefDatabase) -> Source<Self::Value>;
521}
522
523impl HasSource for FunctionLoc {
524 type Value = ast::FnDef;
525
526 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::FnDef> {
527 let node = self.ast_id.to_node(db);
528 Source::new(self.ast_id.file_id(), node)
529 }
530}
531
532impl HasSource for TypeAliasLoc {
533 type Value = ast::TypeAliasDef;
534
535 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::TypeAliasDef> {
536 let node = self.ast_id.to_node(db);
537 Source::new(self.ast_id.file_id(), node)
538 }
539}
540
541impl HasSource for ConstLoc {
542 type Value = ast::ConstDef;
543
544 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::ConstDef> {
545 let node = self.ast_id.to_node(db);
546 Source::new(self.ast_id.file_id(), node)
547 }
548}
549
550impl HasSource for StaticLoc {
551 type Value = ast::StaticDef;
552
553 fn source(&self, db: &impl db::DefDatabase) -> Source<ast::StaticDef> {
554 let node = self.ast_id.to_node(db);
555 Source::new(self.ast_id.file_id(), node)
556 }
557}
558
559pub trait HasChildSource {
560 type ChildId;
561 type Value;
562 fn child_source(
563 &self,
564 db: &impl db::DefDatabase,
565 ) -> Source<ArenaMap<Self::ChildId, Self::Value>>;
566}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 2359386c2..df42ea84a 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -58,8 +58,8 @@ mod tests;
58use std::sync::Arc; 58use std::sync::Arc;
59 59
60use hir_expand::{ 60use hir_expand::{
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId, 61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, InFile,
62 Source, 62 MacroDefId,
63}; 63};
64use once_cell::sync::Lazy; 64use once_cell::sync::Lazy;
65use ra_arena::Arena; 65use ra_arena::Arena;
@@ -261,21 +261,21 @@ impl ModuleData {
261 pub fn definition_source( 261 pub fn definition_source(
262 &self, 262 &self,
263 db: &impl DefDatabase, 263 db: &impl DefDatabase,
264 ) -> Source<Either<ast::SourceFile, ast::Module>> { 264 ) -> InFile<Either<ast::SourceFile, ast::Module>> {
265 if let Some(file_id) = self.definition { 265 if let Some(file_id) = self.definition {
266 let sf = db.parse(file_id).tree(); 266 let sf = db.parse(file_id).tree();
267 return Source::new(file_id.into(), Either::A(sf)); 267 return InFile::new(file_id.into(), Either::A(sf));
268 } 268 }
269 let decl = self.declaration.unwrap(); 269 let decl = self.declaration.unwrap();
270 Source::new(decl.file_id(), Either::B(decl.to_node(db))) 270 InFile::new(decl.file_id, Either::B(decl.to_node(db)))
271 } 271 }
272 272
273 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 273 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
274 /// `None` for the crate root. 274 /// `None` for the crate root.
275 pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { 275 pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<InFile<ast::Module>> {
276 let decl = self.declaration?; 276 let decl = self.declaration?;
277 let value = decl.to_node(db); 277 let value = decl.to_node(db);
278 Some(Source { file_id: decl.file_id(), value }) 278 Some(InFile { file_id: decl.file_id, value })
279 } 279 }
280} 280}
281 281
@@ -309,7 +309,7 @@ mod diagnostics {
309 } 309 }
310 let decl = declaration.to_node(db); 310 let decl = declaration.to_node(db);
311 sink.push(UnresolvedModule { 311 sink.push(UnresolvedModule {
312 file: declaration.file_id(), 312 file: declaration.file_id,
313 decl: AstPtr::new(&decl), 313 decl: AstPtr::new(&decl),
314 candidate: candidate.clone(), 314 candidate: candidate.clone(),
315 }) 315 })
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 6eb106094..5196b67ca 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -22,8 +22,8 @@ use ra_syntax::{
22use test_utils::tested_by; 22use test_utils::tested_by;
23 23
24use crate::{ 24use crate::{
25 attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, LocalImportId, 25 attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, InFile,
26 Source, 26 LocalImportId,
27}; 27};
28 28
29/// `RawItems` is a set of top-level items in a file (except for impls). 29/// `RawItems` is a set of top-level items in a file (except for impls).
@@ -313,7 +313,7 @@ impl RawItemsCollector {
313 313
314 let mut buf = Vec::new(); 314 let mut buf = Vec::new();
315 Path::expand_use_item( 315 Path::expand_use_item(
316 Source { value: use_item, file_id: self.file_id }, 316 InFile { value: use_item, file_id: self.file_id },
317 &self.hygiene, 317 &self.hygiene,
318 |path, use_tree, is_glob, alias| { 318 |path, use_tree, is_glob, alias| {
319 let import_data = ImportData { 319 let import_data = ImportData {
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
index e11530062..e800cc68e 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -668,7 +668,7 @@ fn unresolved_module_diagnostics() {
668 module: LocalModuleId( 668 module: LocalModuleId(
669 0, 669 0,
670 ), 670 ),
671 declaration: AstId { 671 declaration: InFile {
672 file_id: HirFileId( 672 file_id: HirFileId(
673 FileId( 673 FileId(
674 FileId( 674 FileId(
@@ -676,7 +676,7 @@ fn unresolved_module_diagnostics() {
676 ), 676 ),
677 ), 677 ),
678 ), 678 ),
679 file_ast_id: FileAstId { 679 value: FileAstId {
680 raw: ErasedFileAstId( 680 raw: ErasedFileAstId(
681 1, 681 1,
682 ), 682 ),
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 6810a26db..ff252fe44 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -13,7 +13,7 @@ use ra_syntax::{
13 AstNode, 13 AstNode,
14}; 14};
15 15
16use crate::{type_ref::TypeRef, Source}; 16use crate::{type_ref::TypeRef, InFile};
17 17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)] 18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub struct Path { 19pub struct Path {
@@ -67,7 +67,7 @@ pub enum PathKind {
67impl Path { 67impl Path {
68 /// Calls `cb` with all paths, represented by this use item. 68 /// Calls `cb` with all paths, represented by this use item.
69 pub(crate) fn expand_use_item( 69 pub(crate) fn expand_use_item(
70 item_src: Source<ast::UseItem>, 70 item_src: InFile<ast::UseItem>,
71 hygiene: &Hygiene, 71 hygiene: &Hygiene,
72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>), 72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>),
73 ) { 73 ) {
@@ -409,6 +409,36 @@ pub mod known {
409 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) 409 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE])
410 } 410 }
411 411
412 pub fn std_ops_range() -> Path {
413 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TYPE])
414 }
415
416 pub fn std_ops_range_from() -> Path {
417 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FROM_TYPE])
418 }
419
420 pub fn std_ops_range_full() -> Path {
421 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FULL_TYPE])
422 }
423
424 pub fn std_ops_range_inclusive() -> Path {
425 Path::from_simple_segments(
426 PathKind::Abs,
427 vec![name::STD, name::OPS, name::RANGE_INCLUSIVE_TYPE],
428 )
429 }
430
431 pub fn std_ops_range_to() -> Path {
432 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TO_TYPE])
433 }
434
435 pub fn std_ops_range_to_inclusive() -> Path {
436 Path::from_simple_segments(
437 PathKind::Abs,
438 vec![name::STD, name::OPS, name::RANGE_TO_INCLUSIVE_TYPE],
439 )
440 }
441
412 pub fn std_result_result() -> Path { 442 pub fn std_result_result() -> Path {
413 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) 443 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE])
414 } 444 }
diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs
new file mode 100644
index 000000000..27caa02cc
--- /dev/null
+++ b/crates/ra_hir_def/src/src.rs
@@ -0,0 +1,54 @@
1//! Utilities for mapping between hir IDs and the surface syntax.
2
3use hir_expand::InFile;
4use ra_arena::map::ArenaMap;
5use ra_syntax::ast;
6
7use crate::{db::DefDatabase, ConstLoc, FunctionLoc, StaticLoc, TypeAliasLoc};
8
9pub trait HasSource {
10 type Value;
11 fn source(&self, db: &impl DefDatabase) -> InFile<Self::Value>;
12}
13
14impl HasSource for FunctionLoc {
15 type Value = ast::FnDef;
16
17 fn source(&self, db: &impl DefDatabase) -> InFile<ast::FnDef> {
18 let node = self.ast_id.to_node(db);
19 InFile::new(self.ast_id.file_id, node)
20 }
21}
22
23impl HasSource for TypeAliasLoc {
24 type Value = ast::TypeAliasDef;
25
26 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TypeAliasDef> {
27 let node = self.ast_id.to_node(db);
28 InFile::new(self.ast_id.file_id, node)
29 }
30}
31
32impl HasSource for ConstLoc {
33 type Value = ast::ConstDef;
34
35 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ConstDef> {
36 let node = self.ast_id.to_node(db);
37 InFile::new(self.ast_id.file_id, node)
38 }
39}
40
41impl HasSource for StaticLoc {
42 type Value = ast::StaticDef;
43
44 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StaticDef> {
45 let node = self.ast_id.to_node(db);
46 InFile::new(self.ast_id.file_id, node)
47 }
48}
49
50pub trait HasChildSource {
51 type ChildId;
52 type Value;
53 fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>>;
54}
diff --git a/crates/ra_hir_expand/src/diagnostics.rs b/crates/ra_hir_expand/src/diagnostics.rs
index 3d37e9335..108c1e38c 100644
--- a/crates/ra_hir_expand/src/diagnostics.rs
+++ b/crates/ra_hir_expand/src/diagnostics.rs
@@ -18,11 +18,11 @@ use std::{any::Any, fmt};
18 18
19use ra_syntax::{SyntaxNode, SyntaxNodePtr, TextRange}; 19use ra_syntax::{SyntaxNode, SyntaxNodePtr, TextRange};
20 20
21use crate::{db::AstDatabase, Source}; 21use crate::{db::AstDatabase, InFile};
22 22
23pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { 23pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
24 fn message(&self) -> String; 24 fn message(&self) -> String;
25 fn source(&self) -> Source<SyntaxNodePtr>; 25 fn source(&self) -> InFile<SyntaxNodePtr>;
26 fn highlight_range(&self) -> TextRange { 26 fn highlight_range(&self) -> TextRange {
27 self.source().value.range() 27 self.source().value.range()
28 } 28 }
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index b6a739cda..fb88d2ac2 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -13,7 +13,7 @@ pub mod diagnostics;
13pub mod builtin_macro; 13pub mod builtin_macro;
14pub mod quote; 14pub mod quote;
15 15
16use std::hash::{Hash, Hasher}; 16use std::hash::Hash;
17use std::sync::Arc; 17use std::sync::Arc;
18 18
19use ra_db::{salsa, CrateId, FileId}; 19use ra_db::{salsa, CrateId, FileId};
@@ -70,7 +70,7 @@ impl HirFileId {
70 HirFileIdRepr::FileId(file_id) => file_id, 70 HirFileIdRepr::FileId(file_id) => file_id,
71 HirFileIdRepr::MacroFile(macro_file) => { 71 HirFileIdRepr::MacroFile(macro_file) => {
72 let loc = db.lookup_intern_macro(macro_file.macro_call_id); 72 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
73 loc.ast_id.file_id().original_file(db) 73 loc.ast_id.file_id.original_file(db)
74 } 74 }
75 } 75 }
76 } 76 }
@@ -90,9 +90,9 @@ impl HirFileId {
90 let macro_arg = db.macro_arg(macro_file.macro_call_id)?; 90 let macro_arg = db.macro_arg(macro_file.macro_call_id)?;
91 91
92 Some(ExpansionInfo { 92 Some(ExpansionInfo {
93 expanded: Source::new(self, parse.syntax_node()), 93 expanded: InFile::new(self, parse.syntax_node()),
94 arg: Source::new(loc.ast_id.file_id, arg_tt), 94 arg: InFile::new(loc.ast_id.file_id, arg_tt),
95 def: Source::new(loc.ast_id.file_id, def_tt), 95 def: InFile::new(loc.ast_id.file_id, def_tt),
96 macro_arg, 96 macro_arg,
97 macro_def, 97 macro_def,
98 exp_map, 98 exp_map,
@@ -167,9 +167,9 @@ impl MacroCallId {
167/// ExpansionInfo mainly describes how to map text range between src and expanded macro 167/// ExpansionInfo mainly describes how to map text range between src and expanded macro
168#[derive(Debug, Clone, PartialEq, Eq)] 168#[derive(Debug, Clone, PartialEq, Eq)]
169pub struct ExpansionInfo { 169pub struct ExpansionInfo {
170 expanded: Source<SyntaxNode>, 170 expanded: InFile<SyntaxNode>,
171 arg: Source<ast::TokenTree>, 171 arg: InFile<ast::TokenTree>,
172 def: Source<ast::TokenTree>, 172 def: InFile<ast::TokenTree>,
173 173
174 macro_def: Arc<(db::TokenExpander, mbe::TokenMap)>, 174 macro_def: Arc<(db::TokenExpander, mbe::TokenMap)>,
175 macro_arg: Arc<(tt::Subtree, mbe::TokenMap)>, 175 macro_arg: Arc<(tt::Subtree, mbe::TokenMap)>,
@@ -177,7 +177,7 @@ pub struct ExpansionInfo {
177} 177}
178 178
179impl ExpansionInfo { 179impl ExpansionInfo {
180 pub fn map_token_down(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { 180 pub fn map_token_down(&self, token: InFile<&SyntaxToken>) -> Option<InFile<SyntaxToken>> {
181 assert_eq!(token.file_id, self.arg.file_id); 181 assert_eq!(token.file_id, self.arg.file_id);
182 let range = 182 let range =
183 token.value.text_range().checked_sub(self.arg.value.syntax().text_range().start())?; 183 token.value.text_range().checked_sub(self.arg.value.syntax().text_range().start())?;
@@ -191,7 +191,7 @@ impl ExpansionInfo {
191 Some(self.expanded.with_value(token)) 191 Some(self.expanded.with_value(token))
192 } 192 }
193 193
194 pub fn map_token_up(&self, token: Source<&SyntaxToken>) -> Option<Source<SyntaxToken>> { 194 pub fn map_token_up(&self, token: InFile<&SyntaxToken>) -> Option<InFile<SyntaxToken>> {
195 let token_id = self.exp_map.token_by_range(token.value.text_range())?; 195 let token_id = self.exp_map.token_by_range(token.value.text_range())?;
196 196
197 let (token_id, origin) = self.macro_def.0.map_id_up(token_id); 197 let (token_id, origin) = self.macro_def.0.map_id_up(token_id);
@@ -214,73 +214,42 @@ impl ExpansionInfo {
214/// 214///
215/// It is stable across reparses, and can be used as salsa key/value. 215/// It is stable across reparses, and can be used as salsa key/value.
216// FIXME: isn't this just a `Source<FileAstId<N>>` ? 216// FIXME: isn't this just a `Source<FileAstId<N>>` ?
217#[derive(Debug)] 217pub type AstId<N> = InFile<FileAstId<N>>;
218pub struct AstId<N: AstNode> {
219 file_id: HirFileId,
220 file_ast_id: FileAstId<N>,
221}
222
223impl<N: AstNode> Clone for AstId<N> {
224 fn clone(&self) -> AstId<N> {
225 *self
226 }
227}
228impl<N: AstNode> Copy for AstId<N> {}
229
230impl<N: AstNode> PartialEq for AstId<N> {
231 fn eq(&self, other: &Self) -> bool {
232 (self.file_id, self.file_ast_id) == (other.file_id, other.file_ast_id)
233 }
234}
235impl<N: AstNode> Eq for AstId<N> {}
236impl<N: AstNode> Hash for AstId<N> {
237 fn hash<H: Hasher>(&self, hasher: &mut H) {
238 (self.file_id, self.file_ast_id).hash(hasher);
239 }
240}
241 218
242impl<N: AstNode> AstId<N> { 219impl<N: AstNode> AstId<N> {
243 pub fn new(file_id: HirFileId, file_ast_id: FileAstId<N>) -> AstId<N> {
244 AstId { file_id, file_ast_id }
245 }
246
247 pub fn file_id(&self) -> HirFileId {
248 self.file_id
249 }
250
251 pub fn to_node(&self, db: &dyn db::AstDatabase) -> N { 220 pub fn to_node(&self, db: &dyn db::AstDatabase) -> N {
252 let root = db.parse_or_expand(self.file_id).unwrap(); 221 let root = db.parse_or_expand(self.file_id).unwrap();
253 db.ast_id_map(self.file_id).get(self.file_ast_id).to_node(&root) 222 db.ast_id_map(self.file_id).get(self.value).to_node(&root)
254 } 223 }
255} 224}
256 225
257/// `Source<T>` stores a value of `T` inside a particular file/syntax tree. 226/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
258/// 227///
259/// Typical usages are: 228/// Typical usages are:
260/// 229///
261/// * `Source<SyntaxNode>` -- syntax node in a file 230/// * `InFile<SyntaxNode>` -- syntax node in a file
262/// * `Source<ast::FnDef>` -- ast node in a file 231/// * `InFile<ast::FnDef>` -- ast node in a file
263/// * `Source<TextUnit>` -- offset in a file 232/// * `InFile<TextUnit>` -- offset in a file
264#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] 233#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
265pub struct Source<T> { 234pub struct InFile<T> {
266 pub file_id: HirFileId, 235 pub file_id: HirFileId,
267 pub value: T, 236 pub value: T,
268} 237}
269 238
270impl<T> Source<T> { 239impl<T> InFile<T> {
271 pub fn new(file_id: HirFileId, value: T) -> Source<T> { 240 pub fn new(file_id: HirFileId, value: T) -> InFile<T> {
272 Source { file_id, value } 241 InFile { file_id, value }
273 } 242 }
274 243
275 // Similarly, naming here is stupid... 244 // Similarly, naming here is stupid...
276 pub fn with_value<U>(&self, value: U) -> Source<U> { 245 pub fn with_value<U>(&self, value: U) -> InFile<U> {
277 Source::new(self.file_id, value) 246 InFile::new(self.file_id, value)
278 } 247 }
279 248
280 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { 249 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> InFile<U> {
281 Source::new(self.file_id, f(self.value)) 250 InFile::new(self.file_id, f(self.value))
282 } 251 }
283 pub fn as_ref(&self) -> Source<&T> { 252 pub fn as_ref(&self) -> InFile<&T> {
284 self.with_value(&self.value) 253 self.with_value(&self.value)
285 } 254 }
286 pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode { 255 pub fn file_syntax(&self, db: &impl db::AstDatabase) -> SyntaxNode {
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index 7824489d7..05ba37070 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -140,6 +140,12 @@ pub const RESULT_TYPE: Name = Name::new_inline_ascii(6, b"Result");
140pub const OUTPUT_TYPE: Name = Name::new_inline_ascii(6, b"Output"); 140pub const OUTPUT_TYPE: Name = Name::new_inline_ascii(6, b"Output");
141pub const TARGET_TYPE: Name = Name::new_inline_ascii(6, b"Target"); 141pub const TARGET_TYPE: Name = Name::new_inline_ascii(6, b"Target");
142pub const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box"); 142pub const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box");
143pub const RANGE_FROM_TYPE: Name = Name::new_inline_ascii(9, b"RangeFrom");
144pub const RANGE_FULL_TYPE: Name = Name::new_inline_ascii(9, b"RangeFull");
145pub const RANGE_INCLUSIVE_TYPE: Name = Name::new_inline_ascii(14, b"RangeInclusive");
146pub const RANGE_TO_INCLUSIVE_TYPE: Name = Name::new_inline_ascii(16, b"RangeToInclusive");
147pub const RANGE_TO_TYPE: Name = Name::new_inline_ascii(7, b"RangeTo");
148pub const RANGE_TYPE: Name = Name::new_inline_ascii(5, b"Range");
143 149
144// Builtin Macros 150// Builtin Macros
145pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); 151pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file");
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 9ce154593..222a36a9f 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -11,7 +11,7 @@ use ra_db::{salsa, CrateId};
11use crate::{ 11use crate::{
12 method_resolution::CrateImplBlocks, 12 method_resolution::CrateImplBlocks,
13 traits::{AssocTyValue, Impl}, 13 traits::{AssocTyValue, Impl},
14 CallableDef, FnSig, GenericPredicate, ImplTy, InferenceResult, Substs, Ty, TyDefId, TypeCtor, 14 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor,
15 ValueTyDefId, 15 ValueTyDefId,
16}; 16};
17 17
@@ -22,13 +22,18 @@ pub trait HirDatabase: DefDatabase {
22 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; 22 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
23 23
24 #[salsa::invoke(crate::lower::ty_query)] 24 #[salsa::invoke(crate::lower::ty_query)]
25 #[salsa::cycle(crate::lower::ty_recover)]
25 fn ty(&self, def: TyDefId) -> Ty; 26 fn ty(&self, def: TyDefId) -> Ty;
26 27
27 #[salsa::invoke(crate::lower::value_ty_query)] 28 #[salsa::invoke(crate::lower::value_ty_query)]
28 fn value_ty(&self, def: ValueTyDefId) -> Ty; 29 fn value_ty(&self, def: ValueTyDefId) -> Ty;
29 30
30 #[salsa::invoke(crate::lower::impl_ty_query)] 31 #[salsa::invoke(crate::lower::impl_self_ty_query)]
31 fn impl_ty(&self, def: ImplId) -> ImplTy; 32 #[salsa::cycle(crate::lower::impl_self_ty_recover)]
33 fn impl_self_ty(&self, def: ImplId) -> Ty;
34
35 #[salsa::invoke(crate::lower::impl_trait_query)]
36 fn impl_trait(&self, def: ImplId) -> Option<TraitRef>;
32 37
33 #[salsa::invoke(crate::lower::field_types_query)] 38 #[salsa::invoke(crate::lower::field_types_query)]
34 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; 39 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
@@ -37,6 +42,7 @@ pub trait HirDatabase: DefDatabase {
37 fn callable_item_signature(&self, def: CallableDef) -> FnSig; 42 fn callable_item_signature(&self, def: CallableDef) -> FnSig;
38 43
39 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 44 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
45 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
40 fn generic_predicates_for_param( 46 fn generic_predicates_for_param(
41 &self, 47 &self,
42 def: GenericDefId, 48 def: GenericDefId,
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 4a13fac23..5054189cc 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -2,7 +2,7 @@
2 2
3use std::any::Any; 3use std::any::Any;
4 4
5use hir_expand::{db::AstDatabase, name::Name, HirFileId, Source}; 5use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; 6use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
7 7
8pub use hir_def::diagnostics::UnresolvedModule; 8pub use hir_def::diagnostics::UnresolvedModule;
@@ -19,8 +19,8 @@ impl Diagnostic for NoSuchField {
19 "no such field".to_string() 19 "no such field".to_string()
20 } 20 }
21 21
22 fn source(&self) -> Source<SyntaxNodePtr> { 22 fn source(&self) -> InFile<SyntaxNodePtr> {
23 Source { file_id: self.file, value: self.field.into() } 23 InFile { file_id: self.file, value: self.field.into() }
24 } 24 }
25 25
26 fn as_any(&self) -> &(dyn Any + Send + 'static) { 26 fn as_any(&self) -> &(dyn Any + Send + 'static) {
@@ -44,8 +44,8 @@ impl Diagnostic for MissingFields {
44 } 44 }
45 message 45 message
46 } 46 }
47 fn source(&self) -> Source<SyntaxNodePtr> { 47 fn source(&self) -> InFile<SyntaxNodePtr> {
48 Source { file_id: self.file, value: self.field_list.into() } 48 InFile { file_id: self.file, value: self.field_list.into() }
49 } 49 }
50 fn as_any(&self) -> &(dyn Any + Send + 'static) { 50 fn as_any(&self) -> &(dyn Any + Send + 'static) {
51 self 51 self
@@ -72,8 +72,8 @@ impl Diagnostic for MissingOkInTailExpr {
72 fn message(&self) -> String { 72 fn message(&self) -> String {
73 "wrap return expression in Ok".to_string() 73 "wrap return expression in Ok".to_string()
74 } 74 }
75 fn source(&self) -> Source<SyntaxNodePtr> { 75 fn source(&self) -> InFile<SyntaxNodePtr> {
76 Source { file_id: self.file, value: self.expr.into() } 76 InFile { file_id: self.file, value: self.expr.into() }
77 } 77 }
78 fn as_any(&self) -> &(dyn Any + Send + 'static) { 78 fn as_any(&self) -> &(dyn Any + Send + 'static) {
79 self 79 self
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 1e9f4b208..fe259371f 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -577,6 +577,42 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
577 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 577 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
578 Some(struct_.into()) 578 Some(struct_.into())
579 } 579 }
580
581 fn resolve_range_full(&self) -> Option<AdtId> {
582 let path = known::std_ops_range_full();
583 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
584 Some(struct_.into())
585 }
586
587 fn resolve_range(&self) -> Option<AdtId> {
588 let path = known::std_ops_range();
589 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
590 Some(struct_.into())
591 }
592
593 fn resolve_range_inclusive(&self) -> Option<AdtId> {
594 let path = known::std_ops_range_inclusive();
595 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
596 Some(struct_.into())
597 }
598
599 fn resolve_range_from(&self) -> Option<AdtId> {
600 let path = known::std_ops_range_from();
601 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
602 Some(struct_.into())
603 }
604
605 fn resolve_range_to(&self) -> Option<AdtId> {
606 let path = known::std_ops_range_to();
607 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
608 Some(struct_.into())
609 }
610
611 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
612 let path = known::std_ops_range_to_inclusive();
613 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
614 Some(struct_.into())
615 }
580} 616}
581 617
582/// The ID of a type variable. 618/// The ID of a type variable.
@@ -693,7 +729,7 @@ impl Expectation {
693} 729}
694 730
695mod diagnostics { 731mod diagnostics {
696 use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; 732 use hir_def::{expr::ExprId, src::HasSource, FunctionId, Lookup};
697 use hir_expand::diagnostics::DiagnosticSink; 733 use hir_expand::diagnostics::DiagnosticSink;
698 734
699 use crate::{db::HirDatabase, diagnostics::NoSuchField}; 735 use crate::{db::HirDatabase, diagnostics::NoSuchField};
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 719a0f395..064993d34 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -8,7 +8,7 @@ use hir_def::{lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutabilit
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{autoderef, db::HirDatabase, ImplTy, Substs, Ty, TypeCtor, TypeWalk}; 11use crate::{autoderef, db::HirDatabase, Substs, Ty, TypeCtor, TypeWalk};
12 12
13use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; 13use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
14 14
@@ -54,10 +54,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
54 impls 54 impls
55 .iter() 55 .iter()
56 .filter_map(|&impl_id| { 56 .filter_map(|&impl_id| {
57 let trait_ref = match db.impl_ty(impl_id) { 57 let trait_ref = db.impl_trait(impl_id)?;
58 ImplTy::TraitRef(it) => it,
59 ImplTy::Inherent(_) => return None,
60 };
61 58
62 // `CoerseUnsized` has one generic parameter for the target type. 59 // `CoerseUnsized` has one generic parameter for the target type.
63 let cur_from_ty = trait_ref.substs.0.get(0)?; 60 let cur_from_ty = trait_ref.substs.0.get(0)?;
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 2f9ca4bbb..4014f4732 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -12,6 +12,7 @@ use hir_def::{
12 AdtId, ContainerId, Lookup, StructFieldId, 12 AdtId, ContainerId, Lookup, StructFieldId,
13}; 13};
14use hir_expand::name::{self, Name}; 14use hir_expand::name::{self, Name};
15use ra_syntax::ast::RangeOp;
15 16
16use crate::{ 17use crate::{
17 autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, 18 autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data,
@@ -415,6 +416,44 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
415 } 416 }
416 _ => Ty::Unknown, 417 _ => Ty::Unknown,
417 }, 418 },
419 Expr::Range { lhs, rhs, range_type } => {
420 let lhs_ty = lhs.map(|e| self.infer_expr(e, &Expectation::none()));
421 let rhs_expect = lhs_ty
422 .as_ref()
423 .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone()));
424 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
425 match (range_type, lhs_ty, rhs_ty) {
426 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
427 Some(adt) => Ty::simple(TypeCtor::Adt(adt)),
428 None => Ty::Unknown,
429 },
430 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
431 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty),
432 None => Ty::Unknown,
433 },
434 (RangeOp::Inclusive, None, Some(ty)) => {
435 match self.resolve_range_to_inclusive() {
436 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty),
437 None => Ty::Unknown,
438 }
439 }
440 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
441 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty),
442 None => Ty::Unknown,
443 },
444 (RangeOp::Inclusive, Some(_), Some(ty)) => {
445 match self.resolve_range_inclusive() {
446 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty),
447 None => Ty::Unknown,
448 }
449 }
450 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
451 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty),
452 None => Ty::Unknown,
453 },
454 (RangeOp::Inclusive, _, None) => Ty::Unknown,
455 }
456 }
418 Expr::Index { base, index } => { 457 Expr::Index { base, index } => {
419 let _base_ty = self.infer_expr(*base, &Expectation::none()); 458 let _base_ty = self.infer_expr(*base, &Expectation::none());
420 let _index_ty = self.infer_expr(*index, &Expectation::none()); 459 let _index_ty = self.infer_expr(*index, &Expectation::none());
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 14be66836..bbf146418 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -244,7 +244,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
244 ContainerId::ImplId(it) => it, 244 ContainerId::ImplId(it) => it,
245 _ => return None, 245 _ => return None,
246 }; 246 };
247 let self_ty = self.db.impl_ty(impl_id).self_type().clone(); 247 let self_ty = self.db.impl_self_ty(impl_id).clone();
248 let self_ty_substs = self_ty.substs()?; 248 let self_ty_substs = self_ty.substs()?;
249 let actual_substs = actual_def_ty.substs()?; 249 let actual_substs = actual_def_ty.substs()?;
250 250
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index b45c8f82f..3c1f738df 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -486,21 +486,6 @@ impl TypeWalk for TraitRef {
486 } 486 }
487} 487}
488 488
489#[derive(Clone, PartialEq, Eq, Debug)]
490pub enum ImplTy {
491 Inherent(Ty),
492 TraitRef(TraitRef),
493}
494
495impl ImplTy {
496 pub(crate) fn self_type(&self) -> &Ty {
497 match self {
498 ImplTy::Inherent(it) => it,
499 ImplTy::TraitRef(tr) => &tr.substs[0],
500 }
501 }
502}
503
504/// Like `generics::WherePredicate`, but with resolved types: A condition on the 489/// Like `generics::WherePredicate`, but with resolved types: A condition on the
505/// parameters of a generic item. 490/// parameters of a generic item.
506#[derive(Debug, Clone, PartialEq, Eq, Hash)] 491#[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 091c60f4f..32569ac66 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -27,8 +27,8 @@ use crate::{
27 all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, 27 all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice,
28 variant_data, 28 variant_data,
29 }, 29 },
30 FnSig, GenericPredicate, ImplTy, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, 30 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
31 TraitRef, Ty, TypeCtor, TypeWalk, 31 Ty, TypeCtor, TypeWalk,
32}; 32};
33 33
34impl Ty { 34impl Ty {
@@ -179,7 +179,7 @@ impl Ty {
179 let name = resolved_segment.name.clone(); 179 let name = resolved_segment.name.clone();
180 Ty::Param { idx, name } 180 Ty::Param { idx, name }
181 } 181 }
182 TypeNs::SelfType(impl_id) => db.impl_ty(impl_id).self_type().clone(), 182 TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(),
183 TypeNs::AdtSelfType(adt) => db.ty(adt.into()), 183 TypeNs::AdtSelfType(adt) => db.ty(adt.into()),
184 184
185 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), 185 TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()),
@@ -532,6 +532,15 @@ pub(crate) fn generic_predicates_for_param_query(
532 .collect() 532 .collect()
533} 533}
534 534
535pub(crate) fn generic_predicates_for_param_recover(
536 _db: &impl HirDatabase,
537 _cycle: &[String],
538 _def: &GenericDefId,
539 _param_idx: &u32,
540) -> Arc<[GenericPredicate]> {
541 Arc::new([])
542}
543
535impl TraitEnvironment { 544impl TraitEnvironment {
536 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 545 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
537 let predicates = resolver 546 let predicates = resolver
@@ -733,6 +742,11 @@ pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty {
733 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 742 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
734 } 743 }
735} 744}
745
746pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty {
747 Ty::Unknown
748}
749
736pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { 750pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
737 match def { 751 match def {
738 ValueTyDefId::FunctionId(it) => type_for_fn(db, it), 752 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
@@ -743,17 +757,24 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
743 } 757 }
744} 758}
745 759
746pub(crate) fn impl_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> ImplTy { 760pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty {
747 let impl_data = db.impl_data(impl_id); 761 let impl_data = db.impl_data(impl_id);
748 let resolver = impl_id.resolver(db); 762 let resolver = impl_id.resolver(db);
749 let self_ty = Ty::from_hir(db, &resolver, &impl_data.target_type); 763 Ty::from_hir(db, &resolver, &impl_data.target_type)
750 match impl_data.target_trait.as_ref() { 764}
751 Some(trait_ref) => { 765
752 match TraitRef::from_hir(db, &resolver, trait_ref, Some(self_ty.clone())) { 766pub(crate) fn impl_self_ty_recover(
753 Some(it) => ImplTy::TraitRef(it), 767 _db: &impl HirDatabase,
754 None => ImplTy::Inherent(self_ty), 768 _cycle: &[String],
755 } 769 _impl_id: &ImplId,
756 } 770) -> Ty {
757 None => ImplTy::Inherent(self_ty), 771 Ty::Unknown
758 } 772}
773
774pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> {
775 let impl_data = db.impl_data(impl_id);
776 let resolver = impl_id.resolver(db);
777 let self_ty = db.impl_self_ty(impl_id);
778 let target_trait = impl_data.target_trait.as_ref()?;
779 TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone()))
759} 780}
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index ee1936b0e..2bded3dbd 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -19,7 +19,7 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 primitive::{FloatBitness, Uncertain}, 20 primitive::{FloatBitness, Uncertain},
21 utils::all_super_traits, 21 utils::all_super_traits,
22 Canonical, ImplTy, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, 22 Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor,
23}; 23};
24 24
25/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
@@ -58,11 +58,12 @@ impl CrateImplBlocks {
58 let crate_def_map = db.crate_def_map(krate); 58 let crate_def_map = db.crate_def_map(krate);
59 for (_module_id, module_data) in crate_def_map.modules.iter() { 59 for (_module_id, module_data) in crate_def_map.modules.iter() {
60 for &impl_id in module_data.impls.iter() { 60 for &impl_id in module_data.impls.iter() {
61 match db.impl_ty(impl_id) { 61 match db.impl_trait(impl_id) {
62 ImplTy::TraitRef(tr) => { 62 Some(tr) => {
63 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); 63 res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id);
64 } 64 }
65 ImplTy::Inherent(self_ty) => { 65 None => {
66 let self_ty = db.impl_self_ty(impl_id);
66 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { 67 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) {
67 res.impls.entry(self_ty_fp).or_default().push(impl_id); 68 res.impls.entry(self_ty_fp).or_default().push(impl_id);
68 } 69 }
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index c8461b447..c856d6afd 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -8,7 +8,7 @@ use hir_def::{
8 body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId, 8 body::BodySourceMap, db::DefDatabase, nameres::CrateDefMap, AssocItemId, DefWithBodyId,
9 LocalModuleId, Lookup, ModuleDefId, 9 LocalModuleId, Lookup, ModuleDefId,
10}; 10};
11use hir_expand::Source; 11use hir_expand::InFile;
12use insta::assert_snapshot; 12use insta::assert_snapshot;
13use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; 13use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
14use ra_syntax::{ 14use ra_syntax::{
@@ -222,6 +222,56 @@ mod collections {
222} 222}
223 223
224#[test] 224#[test]
225fn infer_ranges() {
226 let (db, pos) = TestDB::with_position(
227 r#"
228//- /main.rs crate:main deps:std
229fn test() {
230 let a = ..;
231 let b = 1..;
232 let c = ..2u32;
233 let d = 1..2usize;
234 let e = ..=10;
235 let f = 'a'..='z';
236
237 let t = (a, b, c, d, e, f);
238 t<|>;
239}
240
241//- /std.rs crate:std
242#[prelude_import] use prelude::*;
243mod prelude {}
244
245pub mod ops {
246 pub struct Range<Idx> {
247 pub start: Idx,
248 pub end: Idx,
249 }
250 pub struct RangeFrom<Idx> {
251 pub start: Idx,
252 }
253 struct RangeFull;
254 pub struct RangeInclusive<Idx> {
255 start: Idx,
256 end: Idx,
257 is_empty: u8,
258 }
259 pub struct RangeTo<Idx> {
260 pub end: Idx,
261 }
262 pub struct RangeToInclusive<Idx> {
263 pub end: Idx,
264 }
265}
266"#,
267 );
268 assert_eq!(
269 "(RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)",
270 type_at_pos(&db, pos),
271 );
272}
273
274#[test]
225fn infer_while_let() { 275fn infer_while_let() {
226 let (db, pos) = TestDB::with_position( 276 let (db, pos) = TestDB::with_position(
227 r#" 277 r#"
@@ -2104,7 +2154,6 @@ fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
2104} 2154}
2105 2155
2106#[test] 2156#[test]
2107#[should_panic] // we currently can't handle this
2108fn recursive_type_alias() { 2157fn recursive_type_alias() {
2109 assert_snapshot!( 2158 assert_snapshot!(
2110 infer(r#" 2159 infer(r#"
@@ -2113,7 +2162,10 @@ type Foo = Foo;
2113type Bar = A<Bar>; 2162type Bar = A<Bar>;
2114fn test(x: Foo) {} 2163fn test(x: Foo) {}
2115"#), 2164"#),
2116 @"" 2165 @r###"
2166 [59; 60) 'x': {unknown}
2167 [67; 69) '{}': ()
2168 "###
2117 ) 2169 )
2118} 2170}
2119 2171
@@ -4626,10 +4678,48 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
4626} 4678}
4627 4679
4628#[test] 4680#[test]
4629// FIXME this is currently a Salsa panic; it would be nicer if it just returned 4681fn trait_impl_self_ty() {
4630// in Unknown, and we should be able to do that once Salsa allows us to handle 4682 let t = type_at(
4631// the cycle. But at least it doesn't overflow for now. 4683 r#"
4632#[should_panic] 4684//- /main.rs
4685trait Trait<T> {
4686 fn foo(&self);
4687}
4688
4689struct S;
4690
4691impl Trait<Self> for S {}
4692
4693fn test() {
4694 S.foo()<|>;
4695}
4696"#,
4697 );
4698 assert_eq!(t, "()");
4699}
4700
4701#[test]
4702fn trait_impl_self_ty_cycle() {
4703 let t = type_at(
4704 r#"
4705//- /main.rs
4706trait Trait {
4707 fn foo(&self);
4708}
4709
4710struct S<T>;
4711
4712impl Trait for S<Self> {}
4713
4714fn test() {
4715 S.foo()<|>;
4716}
4717"#,
4718 );
4719 assert_eq!(t, "{unknown}");
4720}
4721
4722#[test]
4633fn unselected_projection_in_trait_env_cycle_1() { 4723fn unselected_projection_in_trait_env_cycle_1() {
4634 let t = type_at( 4724 let t = type_at(
4635 r#" 4725 r#"
@@ -4650,10 +4740,6 @@ fn test<T: Trait>() where T: Trait2<T::Item> {
4650} 4740}
4651 4741
4652#[test] 4742#[test]
4653// FIXME this is currently a Salsa panic; it would be nicer if it just returned
4654// in Unknown, and we should be able to do that once Salsa allows us to handle
4655// the cycle. But at least it doesn't overflow for now.
4656#[should_panic]
4657fn unselected_projection_in_trait_env_cycle_2() { 4743fn unselected_projection_in_trait_env_cycle_2() {
4658 let t = type_at( 4744 let t = type_at(
4659 r#" 4745 r#"
@@ -4680,7 +4766,7 @@ fn type_at_pos(db: &TestDB, pos: FilePosition) -> String {
4680 for decl in crate_def_map[module.local_id].scope.declarations() { 4766 for decl in crate_def_map[module.local_id].scope.declarations() {
4681 if let ModuleDefId::FunctionId(func) = decl { 4767 if let ModuleDefId::FunctionId(func) = decl {
4682 let (_body, source_map) = db.body_with_source_map(func.into()); 4768 let (_body, source_map) = db.body_with_source_map(func.into());
4683 if let Some(expr_id) = source_map.node_expr(Source::new(pos.file_id.into(), &expr)) { 4769 if let Some(expr_id) = source_map.node_expr(InFile::new(pos.file_id.into(), &expr)) {
4684 let infer = db.infer(func.into()); 4770 let infer = db.infer(func.into());
4685 let ty = &infer[expr_id]; 4771 let ty = &infer[expr_id];
4686 return ty.display(db).to_string(); 4772 return ty.display(db).to_string();
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 35de37e6b..104346ada 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -20,8 +20,8 @@ use ra_db::salsa::{InternId, InternKey};
20 20
21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 21use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
22use crate::{ 22use crate::{
23 db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ImplTy, ProjectionTy, 23 db::HirDatabase, display::HirDisplay, ApplicationTy, GenericPredicate, ProjectionTy, Substs,
24 Substs, TraitRef, Ty, TypeCtor, TypeWalk, 24 TraitRef, Ty, TypeCtor, TypeWalk,
25}; 25};
26 26
27/// This represents a trait whose name we could not resolve. 27/// This represents a trait whose name we could not resolve.
@@ -630,10 +630,7 @@ fn impl_block_datum(
630 chalk_id: chalk_ir::ImplId, 630 chalk_id: chalk_ir::ImplId,
631 impl_id: ImplId, 631 impl_id: ImplId,
632) -> Option<Arc<ImplDatum<ChalkIr>>> { 632) -> Option<Arc<ImplDatum<ChalkIr>>> {
633 let trait_ref = match db.impl_ty(impl_id) { 633 let trait_ref = db.impl_trait(impl_id)?;
634 ImplTy::TraitRef(it) => it,
635 ImplTy::Inherent(_) => return None,
636 };
637 let impl_data = db.impl_data(impl_id); 634 let impl_data = db.impl_data(impl_id);
638 635
639 let generic_params = db.generic_params(impl_id.into()); 636 let generic_params = db.generic_params(impl_id.into());
@@ -787,11 +784,7 @@ fn type_alias_associated_ty_value(
787 _ => panic!("assoc ty value should be in impl"), 784 _ => panic!("assoc ty value should be in impl"),
788 }; 785 };
789 786
790 let trait_ref = match db.impl_ty(impl_id) { 787 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved
791 ImplTy::TraitRef(it) => it,
792 // we don't return any assoc ty values if the impl'd trait can't be resolved
793 ImplTy::Inherent(_) => panic!("assoc ty value should not exist"),
794 };
795 788
796 let assoc_ty = db 789 let assoc_ty = db
797 .trait_data(trait_ref.trait_) 790 .trait_data(trait_ref.trait_)
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index d559dc4d0..b3c323d38 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -18,7 +18,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
18 // Find the calling expression and it's NameRef 18 // Find the calling expression and it's NameRef
19 let calling_node = FnCallNode::with_node(&syntax, position.offset)?; 19 let calling_node = FnCallNode::with_node(&syntax, position.offset)?;
20 let name_ref = calling_node.name_ref()?; 20 let name_ref = calling_node.name_ref()?;
21 let name_ref = hir::Source::new(position.file_id.into(), name_ref.syntax()); 21 let name_ref = hir::InFile::new(position.file_id.into(), name_ref.syntax());
22 22
23 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); 23 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
24 let (mut call_info, has_self) = match &calling_node { 24 let (mut call_info, has_self) = match &calling_node {
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index b8345c91d..ca0a483d4 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -54,13 +54,13 @@ impl<'a> CompletionContext<'a> {
54 let src = hir::ModuleSource::from_position(db, position); 54 let src = hir::ModuleSource::from_position(db, position);
55 let module = hir::Module::from_definition( 55 let module = hir::Module::from_definition(
56 db, 56 db,
57 hir::Source { file_id: position.file_id.into(), value: src }, 57 hir::InFile { file_id: position.file_id.into(), value: src },
58 ); 58 );
59 let token = 59 let token =
60 original_parse.tree().syntax().token_at_offset(position.offset).left_biased()?; 60 original_parse.tree().syntax().token_at_offset(position.offset).left_biased()?;
61 let analyzer = hir::SourceAnalyzer::new( 61 let analyzer = hir::SourceAnalyzer::new(
62 db, 62 db,
63 hir::Source::new(position.file_id.into(), &token.parent()), 63 hir::InFile::new(position.file_id.into(), &token.parent()),
64 Some(position.offset), 64 Some(position.offset),
65 ); 65 );
66 let mut ctx = CompletionContext { 66 let mut ctx = CompletionContext {
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index cc1ccab4b..c50a70d99 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -96,7 +96,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
96 }); 96 });
97 let source_file = db.parse(file_id).tree(); 97 let source_file = db.parse(file_id).tree();
98 let src = 98 let src =
99 hir::Source { file_id: file_id.into(), value: hir::ModuleSource::SourceFile(source_file) }; 99 hir::InFile { file_id: file_id.into(), value: hir::ModuleSource::SourceFile(source_file) };
100 if let Some(m) = hir::Module::from_definition(db, src) { 100 if let Some(m) = hir::Module::from_definition(db, src) {
101 m.diagnostics(db, &mut sink); 101 m.diagnostics(db, &mut sink);
102 }; 102 };
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index 6ac60722b..61dca14ac 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{AssocItem, Either, FieldSource, HasSource, ModuleSource, Source}; 3use hir::{AssocItem, Either, FieldSource, HasSource, InFile, ModuleSource};
4use ra_db::{FileId, SourceDatabase}; 4use ra_db::{FileId, SourceDatabase};
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, DocCommentsOwner, NameOwner}, 6 ast::{self, DocCommentsOwner, NameOwner},
@@ -141,7 +141,7 @@ impl NavigationTarget {
141 /// Allows `NavigationTarget` to be created from a `NameOwner` 141 /// Allows `NavigationTarget` to be created from a `NameOwner`
142 pub(crate) fn from_named( 142 pub(crate) fn from_named(
143 db: &RootDatabase, 143 db: &RootDatabase,
144 node: Source<&dyn ast::NameOwner>, 144 node: InFile<&dyn ast::NameOwner>,
145 docs: Option<String>, 145 docs: Option<String>,
146 description: Option<String>, 146 description: Option<String>,
147 ) -> NavigationTarget { 147 ) -> NavigationTarget {
diff --git a/crates/ra_ide/src/expand.rs b/crates/ra_ide/src/expand.rs
index 2f1abf509..216d5cfec 100644
--- a/crates/ra_ide/src/expand.rs
+++ b/crates/ra_ide/src/expand.rs
@@ -1,13 +1,13 @@
1//! Utilities to work with files, produced by macros. 1//! Utilities to work with files, produced by macros.
2use std::iter::successors; 2use std::iter::successors;
3 3
4use hir::Source; 4use hir::InFile;
5use ra_db::FileId; 5use ra_db::FileId;
6use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken}; 6use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken};
7 7
8use crate::{db::RootDatabase, FileRange}; 8use crate::{db::RootDatabase, FileRange};
9 9
10pub(crate) fn original_range(db: &RootDatabase, node: Source<&SyntaxNode>) -> FileRange { 10pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange {
11 let expansion = match node.file_id.expansion_info(db) { 11 let expansion = match node.file_id.expansion_info(db) {
12 None => { 12 None => {
13 return FileRange { 13 return FileRange {
@@ -44,8 +44,8 @@ pub(crate) fn descend_into_macros(
44 db: &RootDatabase, 44 db: &RootDatabase,
45 file_id: FileId, 45 file_id: FileId,
46 token: SyntaxToken, 46 token: SyntaxToken,
47) -> Source<SyntaxToken> { 47) -> InFile<SyntaxToken> {
48 let src = Source::new(file_id.into(), token); 48 let src = InFile::new(file_id.into(), token);
49 49
50 successors(Some(src), |token| { 50 successors(Some(src), |token| {
51 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 51 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
diff --git a/crates/ra_ide/src/expand_macro.rs b/crates/ra_ide/src/expand_macro.rs
index abc602244..862c03304 100644
--- a/crates/ra_ide/src/expand_macro.rs
+++ b/crates/ra_ide/src/expand_macro.rs
@@ -22,7 +22,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
22 let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)?; 22 let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)?;
23 let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; 23 let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?;
24 24
25 let source = hir::Source::new(position.file_id.into(), mac.syntax()); 25 let source = hir::InFile::new(position.file_id.into(), mac.syntax());
26 let expanded = expand_macro_recur(db, source, source.with_value(&mac))?; 26 let expanded = expand_macro_recur(db, source, source.with_value(&mac))?;
27 27
28 // FIXME: 28 // FIXME:
@@ -34,8 +34,8 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
34 34
35fn expand_macro_recur( 35fn expand_macro_recur(
36 db: &RootDatabase, 36 db: &RootDatabase,
37 source: hir::Source<&SyntaxNode>, 37 source: hir::InFile<&SyntaxNode>,
38 macro_call: hir::Source<&ast::MacroCall>, 38 macro_call: hir::InFile<&ast::MacroCall>,
39) -> Option<SyntaxNode> { 39) -> Option<SyntaxNode> {
40 let analyzer = hir::SourceAnalyzer::new(db, source, None); 40 let analyzer = hir::SourceAnalyzer::new(db, source, None);
41 let expansion = analyzer.expand(db, macro_call)?; 41 let expansion = analyzer.expand(db, macro_call)?;
@@ -46,7 +46,7 @@ fn expand_macro_recur(
46 let mut replaces = FxHashMap::default(); 46 let mut replaces = FxHashMap::default();
47 47
48 for child in children.into_iter() { 48 for child in children.into_iter() {
49 let node = hir::Source::new(macro_file_id, &child); 49 let node = hir::InFile::new(macro_file_id, &child);
50 if let Some(new_node) = expand_macro_recur(db, source, node) { 50 if let Some(new_node) = expand_macro_recur(db, source, node) {
51 // Replace the whole node if it is root 51 // Replace the whole node if it is root
52 // `replace_descendants` will not replace the parent node 52 // `replace_descendants` will not replace the parent node
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index c10a6c844..76a741207 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{db::AstDatabase, Source}; 3use hir::{db::AstDatabase, InFile};
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{self, DocCommentsOwner}, 5 ast::{self, DocCommentsOwner},
6 match_ast, AstNode, SyntaxNode, 6 match_ast, AstNode, SyntaxNode,
@@ -58,7 +58,7 @@ impl ReferenceResult {
58 58
59pub(crate) fn reference_definition( 59pub(crate) fn reference_definition(
60 db: &RootDatabase, 60 db: &RootDatabase,
61 name_ref: Source<&ast::NameRef>, 61 name_ref: InFile<&ast::NameRef>,
62) -> ReferenceResult { 62) -> ReferenceResult {
63 use self::ReferenceResult::*; 63 use self::ReferenceResult::*;
64 64
@@ -94,7 +94,7 @@ pub(crate) fn reference_definition(
94 94
95pub(crate) fn name_definition( 95pub(crate) fn name_definition(
96 db: &RootDatabase, 96 db: &RootDatabase,
97 name: Source<&ast::Name>, 97 name: InFile<&ast::Name>,
98) -> Option<Vec<NavigationTarget>> { 98) -> Option<Vec<NavigationTarget>> {
99 let parent = name.value.syntax().parent()?; 99 let parent = name.value.syntax().parent()?;
100 100
@@ -115,7 +115,7 @@ pub(crate) fn name_definition(
115 None 115 None
116} 116}
117 117
118fn named_target(db: &RootDatabase, node: Source<&SyntaxNode>) -> Option<NavigationTarget> { 118fn named_target(db: &RootDatabase, node: InFile<&SyntaxNode>) -> Option<NavigationTarget> {
119 match_ast! { 119 match_ast! {
120 match (node.value) { 120 match (node.value) {
121 ast::StructDef(it) => { 121 ast::StructDef(it) => {
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 260a7b869..d8185c688 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -227,7 +227,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
227 .take_while(|it| it.text_range() == leaf_node.text_range()) 227 .take_while(|it| it.text_range() == leaf_node.text_range())
228 .find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?; 228 .find(|it| ast::Expr::cast(it.clone()).is_some() || ast::Pat::cast(it.clone()).is_some())?;
229 let analyzer = 229 let analyzer =
230 hir::SourceAnalyzer::new(db, hir::Source::new(frange.file_id.into(), &node), None); 230 hir::SourceAnalyzer::new(db, hir::InFile::new(frange.file_id.into(), &node), None);
231 let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e)) 231 let ty = if let Some(ty) = ast::Expr::cast(node.clone()).and_then(|e| analyzer.type_of(db, &e))
232 { 232 {
233 ty 233 ty
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/impls.rs
index aa480e399..9b165ee2a 100644
--- a/crates/ra_ide/src/impls.rs
+++ b/crates/ra_ide/src/impls.rs
@@ -16,7 +16,7 @@ pub(crate) fn goto_implementation(
16 let src = hir::ModuleSource::from_position(db, position); 16 let src = hir::ModuleSource::from_position(db, position);
17 let module = hir::Module::from_definition( 17 let module = hir::Module::from_definition(
18 db, 18 db,
19 hir::Source { file_id: position.file_id.into(), value: src }, 19 hir::InFile { file_id: position.file_id.into(), value: src },
20 )?; 20 )?;
21 21
22 if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) { 22 if let Some(nominal_def) = find_node_at_offset::<ast::NominalDef>(&syntax, position.offset) {
@@ -42,15 +42,15 @@ fn impls_for_def(
42) -> Option<Vec<NavigationTarget>> { 42) -> Option<Vec<NavigationTarget>> {
43 let ty = match node { 43 let ty = match node {
44 ast::NominalDef::StructDef(def) => { 44 ast::NominalDef::StructDef(def) => {
45 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; 45 let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
46 hir::Struct::from_source(db, src)?.ty(db) 46 hir::Struct::from_source(db, src)?.ty(db)
47 } 47 }
48 ast::NominalDef::EnumDef(def) => { 48 ast::NominalDef::EnumDef(def) => {
49 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; 49 let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
50 hir::Enum::from_source(db, src)?.ty(db) 50 hir::Enum::from_source(db, src)?.ty(db)
51 } 51 }
52 ast::NominalDef::UnionDef(def) => { 52 ast::NominalDef::UnionDef(def) => {
53 let src = hir::Source { file_id: position.file_id.into(), value: def.clone() }; 53 let src = hir::InFile { file_id: position.file_id.into(), value: def.clone() };
54 hir::Union::from_source(db, src)?.ty(db) 54 hir::Union::from_source(db, src)?.ty(db)
55 } 55 }
56 }; 56 };
@@ -73,7 +73,7 @@ fn impls_for_trait(
73 node: &ast::TraitDef, 73 node: &ast::TraitDef,
74 module: hir::Module, 74 module: hir::Module,
75) -> Option<Vec<NavigationTarget>> { 75) -> Option<Vec<NavigationTarget>> {
76 let src = hir::Source { file_id: position.file_id.into(), value: node.clone() }; 76 let src = hir::InFile { file_id: position.file_id.into(), value: node.clone() };
77 let tr = hir::Trait::from_source(db, src)?; 77 let tr = hir::Trait::from_source(db, src)?;
78 78
79 let krate = module.krate(); 79 let krate = module.krate();
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index 45149bf0c..59eced9d7 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -38,7 +38,7 @@ fn get_inlay_hints(
38 node: &SyntaxNode, 38 node: &SyntaxNode,
39 max_inlay_hint_length: Option<usize>, 39 max_inlay_hint_length: Option<usize>,
40) -> Option<Vec<InlayHint>> { 40) -> Option<Vec<InlayHint>> {
41 let analyzer = SourceAnalyzer::new(db, hir::Source::new(file_id.into(), node), None); 41 let analyzer = SourceAnalyzer::new(db, hir::InFile::new(file_id.into(), node), None);
42 match_ast! { 42 match_ast! {
43 match node { 43 match node {
44 ast::LetStmt(it) => { 44 ast::LetStmt(it) => {
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs
index 6027e7d54..616d69fce 100644
--- a/crates/ra_ide/src/parent_module.rs
+++ b/crates/ra_ide/src/parent_module.rs
@@ -10,7 +10,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
10 let src = hir::ModuleSource::from_position(db, position); 10 let src = hir::ModuleSource::from_position(db, position);
11 let module = match hir::Module::from_definition( 11 let module = match hir::Module::from_definition(
12 db, 12 db,
13 hir::Source { file_id: position.file_id.into(), value: src }, 13 hir::InFile { file_id: position.file_id.into(), value: src },
14 ) { 14 ) {
15 None => return Vec::new(), 15 None => return Vec::new(),
16 Some(it) => it, 16 Some(it) => it,
@@ -23,7 +23,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
23pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { 23pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
24 let src = hir::ModuleSource::from_file_id(db, file_id); 24 let src = hir::ModuleSource::from_file_id(db, file_id);
25 let module = 25 let module =
26 match hir::Module::from_definition(db, hir::Source { file_id: file_id.into(), value: src }) 26 match hir::Module::from_definition(db, hir::InFile { file_id: file_id.into(), value: src })
27 { 27 {
28 Some(it) => it, 28 Some(it) => it,
29 None => return Vec::new(), 29 None => return Vec::new(),
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index 21a1ea69e..3e7bfd872 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -14,7 +14,7 @@ mod name_definition;
14mod rename; 14mod rename;
15mod search_scope; 15mod search_scope;
16 16
17use hir::Source; 17use hir::InFile;
18use once_cell::unsync::Lazy; 18use once_cell::unsync::Lazy;
19use ra_db::{SourceDatabase, SourceDatabaseExt}; 19use ra_db::{SourceDatabase, SourceDatabaseExt};
20use ra_prof::profile; 20use ra_prof::profile;
@@ -107,12 +107,12 @@ fn find_name<'a>(
107 position: FilePosition, 107 position: FilePosition,
108) -> Option<RangeInfo<(String, NameDefinition)>> { 108) -> Option<RangeInfo<(String, NameDefinition)>> {
109 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) { 109 if let Some(name) = find_node_at_offset::<ast::Name>(&syntax, position.offset) {
110 let def = classify_name(db, Source::new(position.file_id.into(), &name))?; 110 let def = classify_name(db, InFile::new(position.file_id.into(), &name))?;
111 let range = name.syntax().text_range(); 111 let range = name.syntax().text_range();
112 return Some(RangeInfo::new(range, (name.text().to_string(), def))); 112 return Some(RangeInfo::new(range, (name.text().to_string(), def)));
113 } 113 }
114 let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?; 114 let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?;
115 let def = classify_name_ref(db, Source::new(position.file_id.into(), &name_ref))?; 115 let def = classify_name_ref(db, InFile::new(position.file_id.into(), &name_ref))?;
116 let range = name_ref.syntax().text_range(); 116 let range = name_ref.syntax().text_range();
117 Some(RangeInfo::new(range, (name_ref.text().to_string(), def))) 117 Some(RangeInfo::new(range, (name_ref.text().to_string(), def)))
118} 118}
@@ -144,7 +144,7 @@ fn process_definition(
144 continue; 144 continue;
145 } 145 }
146 } 146 }
147 if let Some(d) = classify_name_ref(db, Source::new(file_id.into(), &name_ref)) { 147 if let Some(d) = classify_name_ref(db, InFile::new(file_id.into(), &name_ref)) {
148 if d == def { 148 if d == def {
149 refs.push(FileRange { file_id, range }); 149 refs.push(FileRange { file_id, range });
150 } 150 }
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index 5cea805ec..b716d32e5 100644
--- a/crates/ra_ide/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -1,6 +1,6 @@
1//! Functions that are used to classify an element from its definition or reference. 1//! Functions that are used to classify an element from its definition or reference.
2 2
3use hir::{FromSource, Module, ModuleSource, PathResolution, Source, SourceAnalyzer}; 3use hir::{FromSource, InFile, Module, ModuleSource, PathResolution, SourceAnalyzer};
4use ra_prof::profile; 4use ra_prof::profile;
5use ra_syntax::{ast, match_ast, AstNode}; 5use ra_syntax::{ast, match_ast, AstNode};
6use test_utils::tested_by; 6use test_utils::tested_by;
@@ -11,7 +11,7 @@ use super::{
11}; 11};
12use crate::db::RootDatabase; 12use crate::db::RootDatabase;
13 13
14pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Option<NameDefinition> { 14pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Option<NameDefinition> {
15 let _p = profile("classify_name"); 15 let _p = profile("classify_name");
16 let parent = name.value.syntax().parent()?; 16 let parent = name.value.syntax().parent()?;
17 17
@@ -117,7 +117,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
117 117
118pub(crate) fn classify_name_ref( 118pub(crate) fn classify_name_ref(
119 db: &RootDatabase, 119 db: &RootDatabase,
120 name_ref: Source<&ast::NameRef>, 120 name_ref: InFile<&ast::NameRef>,
121) -> Option<NameDefinition> { 121) -> Option<NameDefinition> {
122 let _p = profile("classify_name_ref"); 122 let _p = profile("classify_name_ref");
123 123
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index d58496049..b804d5f6d 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -2,7 +2,7 @@
2 2
3use hir::ModuleSource; 3use hir::ModuleSource;
4use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt}; 4use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt};
5use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode}; 5use ra_syntax::{algo::find_node_at_offset, ast, tokenize, AstNode, SyntaxKind, SyntaxNode};
6use ra_text_edit::TextEdit; 6use ra_text_edit::TextEdit;
7 7
8use crate::{ 8use crate::{
@@ -17,6 +17,13 @@ pub(crate) fn rename(
17 position: FilePosition, 17 position: FilePosition,
18 new_name: &str, 18 new_name: &str,
19) -> Option<RangeInfo<SourceChange>> { 19) -> Option<RangeInfo<SourceChange>> {
20 let tokens = tokenize(new_name);
21 if tokens.len() != 1
22 || (tokens[0].kind != SyntaxKind::IDENT && tokens[0].kind != SyntaxKind::UNDERSCORE)
23 {
24 return None;
25 }
26
20 let parse = db.parse(position.file_id); 27 let parse = db.parse(position.file_id);
21 if let Some((ast_name, ast_module)) = 28 if let Some((ast_name, ast_module)) =
22 find_name_and_module_at_offset(parse.tree().syntax(), position) 29 find_name_and_module_at_offset(parse.tree().syntax(), position)
@@ -55,7 +62,7 @@ fn rename_mod(
55) -> Option<SourceChange> { 62) -> Option<SourceChange> {
56 let mut source_file_edits = Vec::new(); 63 let mut source_file_edits = Vec::new();
57 let mut file_system_edits = Vec::new(); 64 let mut file_system_edits = Vec::new();
58 let module_src = hir::Source { file_id: position.file_id.into(), value: ast_module.clone() }; 65 let module_src = hir::InFile { file_id: position.file_id.into(), value: ast_module.clone() };
59 if let Some(module) = hir::Module::from_declaration(db, module_src) { 66 if let Some(module) = hir::Module::from_declaration(db, module_src) {
60 let src = module.definition_source(db); 67 let src = module.definition_source(db);
61 let file_id = src.file_id.original_file(db); 68 let file_id = src.file_id.original_file(db);
@@ -124,6 +131,49 @@ mod tests {
124 }; 131 };
125 132
126 #[test] 133 #[test]
134 fn test_rename_to_underscore() {
135 test_rename(
136 r#"
137 fn main() {
138 let i<|> = 1;
139 }"#,
140 "_",
141 r#"
142 fn main() {
143 let _ = 1;
144 }"#,
145 );
146 }
147
148 #[test]
149 fn test_rename_to_raw_identifier() {
150 test_rename(
151 r#"
152 fn main() {
153 let i<|> = 1;
154 }"#,
155 "r#fn",
156 r#"
157 fn main() {
158 let r#fn = 1;
159 }"#,
160 );
161 }
162
163 #[test]
164 fn test_rename_to_invalid_identifier() {
165 let (analysis, position) = single_file_with_position(
166 "
167 fn main() {
168 let i<|> = 1;
169 }",
170 );
171 let new_name = "invalid!";
172 let source_change = analysis.rename(position, new_name).unwrap();
173 assert!(source_change.is_none());
174 }
175
176 #[test]
127 fn test_rename_for_local() { 177 fn test_rename_for_local() {
128 test_rename( 178 test_rename(
129 r#" 179 r#"
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 8039a5164..e213e1a06 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::Source; 3use hir::InFile;
4use itertools::Itertools; 4use itertools::Itertools;
5use ra_db::SourceDatabase; 5use ra_db::SourceDatabase;
6use ra_syntax::{ 6use ra_syntax::{
@@ -66,8 +66,8 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti
66 return None; 66 return None;
67 } 67 }
68 let range = module.syntax().text_range(); 68 let range = module.syntax().text_range();
69 let src = hir::ModuleSource::from_child_node(db, Source::new(file_id.into(), &module.syntax())); 69 let src = hir::ModuleSource::from_child_node(db, InFile::new(file_id.into(), &module.syntax()));
70 let module = hir::Module::from_definition(db, Source::new(file_id.into(), src))?; 70 let module = hir::Module::from_definition(db, InFile::new(file_id.into(), src))?;
71 71
72 let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); 72 let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::");
73 Some(Runnable { range, kind: RunnableKind::TestMod { path } }) 73 Some(Runnable { range, kind: RunnableKind::TestMod { path } })
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 9a3e4c82f..e6a79541f 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -2,7 +2,7 @@
2 2
3use rustc_hash::{FxHashMap, FxHashSet}; 3use rustc_hash::{FxHashMap, FxHashSet};
4 4
5use hir::{Name, Source}; 5use hir::{InFile, Name};
6use ra_db::SourceDatabase; 6use ra_db::SourceDatabase;
7use ra_prof::profile; 7use ra_prof::profile;
8use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; 8use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T};
@@ -81,7 +81,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
81 81
82 let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); 82 let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap();
83 let name_kind = 83 let name_kind =
84 classify_name_ref(db, Source::new(file_id.into(), &name_ref)).map(|d| d.kind); 84 classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind);
85 85
86 if let Some(Local(local)) = &name_kind { 86 if let Some(Local(local)) = &name_kind {
87 if let Some(name) = local.name(db) { 87 if let Some(name) = local.name(db) {
@@ -95,7 +95,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
95 NAME => { 95 NAME => {
96 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); 96 let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap();
97 let name_kind = 97 let name_kind =
98 classify_name(db, Source::new(file_id.into(), &name)).map(|d| d.kind); 98 classify_name(db, InFile::new(file_id.into(), &name)).map(|d| d.kind);
99 99
100 if let Some(Local(local)) = &name_kind { 100 if let Some(Local(local)) = &name_kind {
101 if let Some(name) = local.name(db) { 101 if let Some(name) = local.name(db) {
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index c81fa7f67..ca47ff5e1 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -480,8 +480,6 @@ pub fn handle_prepare_rename(
480 let _p = profile("handle_prepare_rename"); 480 let _p = profile("handle_prepare_rename");
481 let position = params.try_conv_with(&world)?; 481 let position = params.try_conv_with(&world)?;
482 482
483 // We support renaming references like handle_rename does.
484 // In the future we may want to reject the renaming of things like keywords here too.
485 let optional_change = world.analysis().rename(position, "dummy")?; 483 let optional_change = world.analysis().rename(position, "dummy")?;
486 let range = match optional_change { 484 let range = match optional_change {
487 None => return Ok(None), 485 None => return Ok(None),
diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
index 20c251ff4..4c00b8f30 100644
--- a/crates/ra_tt/src/lib.rs
+++ b/crates/ra_tt/src/lib.rs
@@ -33,14 +33,14 @@ impl TokenId {
33 } 33 }
34} 34}
35 35
36#[derive(Debug, Clone, PartialEq, Eq)] 36#[derive(Debug, Clone, PartialEq, Eq, Hash)]
37pub enum TokenTree { 37pub enum TokenTree {
38 Leaf(Leaf), 38 Leaf(Leaf),
39 Subtree(Subtree), 39 Subtree(Subtree),
40} 40}
41impl_froms!(TokenTree: Leaf, Subtree); 41impl_froms!(TokenTree: Leaf, Subtree);
42 42
43#[derive(Debug, Clone, PartialEq, Eq)] 43#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub enum Leaf { 44pub enum Leaf {
45 Literal(Literal), 45 Literal(Literal),
46 Punct(Punct), 46 Punct(Punct),
@@ -48,13 +48,13 @@ pub enum Leaf {
48} 48}
49impl_froms!(Leaf: Literal, Punct, Ident); 49impl_froms!(Leaf: Literal, Punct, Ident);
50 50
51#[derive(Debug, Clone, PartialEq, Eq)] 51#[derive(Debug, Clone, PartialEq, Eq, Hash)]
52pub struct Subtree { 52pub struct Subtree {
53 pub delimiter: Delimiter, 53 pub delimiter: Delimiter,
54 pub token_trees: Vec<TokenTree>, 54 pub token_trees: Vec<TokenTree>,
55} 55}
56 56
57#[derive(Clone, Copy, Debug, PartialEq, Eq)] 57#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
58pub enum Delimiter { 58pub enum Delimiter {
59 Parenthesis, 59 Parenthesis,
60 Brace, 60 Brace,
@@ -62,24 +62,24 @@ pub enum Delimiter {
62 None, 62 None,
63} 63}
64 64
65#[derive(Debug, Clone, PartialEq, Eq)] 65#[derive(Debug, Clone, PartialEq, Eq, Hash)]
66pub struct Literal { 66pub struct Literal {
67 pub text: SmolStr, 67 pub text: SmolStr,
68} 68}
69 69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)] 70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
71pub struct Punct { 71pub struct Punct {
72 pub char: char, 72 pub char: char,
73 pub spacing: Spacing, 73 pub spacing: Spacing,
74} 74}
75 75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)] 76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
77pub enum Spacing { 77pub enum Spacing {
78 Alone, 78 Alone,
79 Joint, 79 Joint,
80} 80}
81 81
82#[derive(Debug, Clone, PartialEq, Eq)] 82#[derive(Debug, Clone, PartialEq, Eq, Hash)]
83pub struct Ident { 83pub struct Ident {
84 pub text: SmolStr, 84 pub text: SmolStr,
85 pub id: TokenId, 85 pub id: TokenId,