aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-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.rs24
-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.rs45
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs55
-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/resolver.rs38
-rw-r--r--crates/ra_hir_def/src/src.rs54
19 files changed, 265 insertions, 127 deletions
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..239f35229 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};
@@ -15,9 +15,10 @@ use rustc_hash::FxHashMap;
15use crate::{ 15use crate::{
16 db::DefDatabase, 16 db::DefDatabase,
17 expr::{Expr, ExprId, Pat, PatId}, 17 expr::{Expr, ExprId, Pat, PatId},
18 nameres::CrateDefMap, 18 nameres::{BuiltinShadowMode, 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> {
@@ -82,7 +83,10 @@ impl Expander {
82 } 83 }
83 84
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 85 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
85 self.crate_def_map.resolve_path(db, self.module.local_id, path).0.take_macros() 86 self.crate_def_map
87 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other)
88 .0
89 .take_macros()
86 } 90 }
87} 91}
88 92
@@ -115,10 +119,10 @@ pub struct Body {
115} 119}
116 120
117pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 121pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
118pub type ExprSource = Source<ExprPtr>; 122pub type ExprSource = InFile<ExprPtr>;
119 123
120pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; 124pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
121pub type PatSource = Source<PatPtr>; 125pub type PatSource = InFile<PatPtr>;
122 126
123/// An item body together with the mapping from syntax nodes to HIR expression 127/// 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 128/// IDs. This is needed to go from e.g. a position in a file to the HIR
@@ -205,7 +209,7 @@ impl BodySourceMap {
205 self.expr_map_back.get(expr).copied() 209 self.expr_map_back.get(expr).copied()
206 } 210 }
207 211
208 pub fn node_expr(&self, node: Source<&ast::Expr>) -> Option<ExprId> { 212 pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprId> {
209 let src = node.map(|it| Either::A(AstPtr::new(it))); 213 let src = node.map(|it| Either::A(AstPtr::new(it)));
210 self.expr_map.get(&src).cloned() 214 self.expr_map.get(&src).cloned()
211 } 215 }
@@ -214,7 +218,7 @@ impl BodySourceMap {
214 self.pat_map_back.get(pat).copied() 218 self.pat_map_back.get(pat).copied()
215 } 219 }
216 220
217 pub fn node_pat(&self, node: Source<&ast::Pat>) -> Option<PatId> { 221 pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
218 let src = node.map(|it| Either::A(AstPtr::new(it))); 222 let src = node.map(|it| Either::A(AstPtr::new(it)));
219 self.pat_map.get(&src).cloned() 223 self.pat_map.get(&src).cloned()
220 } 224 }
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..3e1521870 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;
@@ -149,6 +149,15 @@ static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
149 .collect() 149 .collect()
150}); 150});
151 151
152/// Shadow mode for builtin type which can be shadowed by module.
153#[derive(Debug, Copy, Clone, PartialEq, Eq)]
154pub enum BuiltinShadowMode {
155 // Prefer Module
156 Module,
157 // Prefer Other Types
158 Other,
159}
160
152/// Legacy macros can only be accessed through special methods like `get_legacy_macros`. 161/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
153/// Other methods will only resolve values, types and module scoped macros only. 162/// Other methods will only resolve values, types and module scoped macros only.
154impl ModuleScope { 163impl ModuleScope {
@@ -178,8 +187,20 @@ impl ModuleScope {
178 } 187 }
179 188
180 /// Get a name from current module scope, legacy macros are not included 189 /// Get a name from current module scope, legacy macros are not included
181 pub fn get(&self, name: &Name) -> Option<&Resolution> { 190 pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
182 self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)) 191 match shadow {
192 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
193 BuiltinShadowMode::Other => {
194 let item = self.items.get(name);
195 if let Some(res) = item {
196 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
197 return BUILTIN_SCOPE.get(name).or(item);
198 }
199 }
200
201 item.or_else(|| BUILTIN_SCOPE.get(name))
202 }
203 }
183 } 204 }
184 205
185 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a { 206 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
@@ -250,8 +271,10 @@ impl CrateDefMap {
250 db: &impl DefDatabase, 271 db: &impl DefDatabase,
251 original_module: LocalModuleId, 272 original_module: LocalModuleId,
252 path: &Path, 273 path: &Path,
274 shadow: BuiltinShadowMode,
253 ) -> (PerNs, Option<usize>) { 275 ) -> (PerNs, Option<usize>) {
254 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); 276 let res =
277 self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path, shadow);
255 (res.resolved_def, res.segment_index) 278 (res.resolved_def, res.segment_index)
256 } 279 }
257} 280}
@@ -261,21 +284,21 @@ impl ModuleData {
261 pub fn definition_source( 284 pub fn definition_source(
262 &self, 285 &self,
263 db: &impl DefDatabase, 286 db: &impl DefDatabase,
264 ) -> Source<Either<ast::SourceFile, ast::Module>> { 287 ) -> InFile<Either<ast::SourceFile, ast::Module>> {
265 if let Some(file_id) = self.definition { 288 if let Some(file_id) = self.definition {
266 let sf = db.parse(file_id).tree(); 289 let sf = db.parse(file_id).tree();
267 return Source::new(file_id.into(), Either::A(sf)); 290 return InFile::new(file_id.into(), Either::A(sf));
268 } 291 }
269 let decl = self.declaration.unwrap(); 292 let decl = self.declaration.unwrap();
270 Source::new(decl.file_id(), Either::B(decl.to_node(db))) 293 InFile::new(decl.file_id, Either::B(decl.to_node(db)))
271 } 294 }
272 295
273 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 296 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
274 /// `None` for the crate root. 297 /// `None` for the crate root.
275 pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<Source<ast::Module>> { 298 pub fn declaration_source(&self, db: &impl DefDatabase) -> Option<InFile<ast::Module>> {
276 let decl = self.declaration?; 299 let decl = self.declaration?;
277 let value = decl.to_node(db); 300 let value = decl.to_node(db);
278 Some(Source { file_id: decl.file_id(), value }) 301 Some(InFile { file_id: decl.file_id, value })
279 } 302 }
280} 303}
281 304
@@ -309,7 +332,7 @@ mod diagnostics {
309 } 332 }
310 let decl = declaration.to_node(db); 333 let decl = declaration.to_node(db);
311 sink.push(UnresolvedModule { 334 sink.push(UnresolvedModule {
312 file: declaration.file_id(), 335 file: declaration.file_id,
313 decl: AstPtr::new(&decl), 336 decl: AstPtr::new(&decl),
314 candidate: candidate.clone(), 337 candidate: candidate.clone(),
315 }) 338 })
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index fd8245113..d4bfcae1d 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -19,7 +19,7 @@ use crate::{
19 db::DefDatabase, 19 db::DefDatabase,
20 nameres::{ 20 nameres::{
21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
22 raw, CrateDefMap, ModuleData, Resolution, ResolveMode, 22 raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode,
23 }, 23 },
24 path::{Path, PathKind}, 24 path::{Path, PathKind},
25 per_ns::PerNs, 25 per_ns::PerNs,
@@ -299,6 +299,7 @@ where
299 ResolveMode::Import, 299 ResolveMode::Import,
300 module_id, 300 module_id,
301 &import.path, 301 &import.path,
302 BuiltinShadowMode::Module,
302 ); 303 );
303 304
304 (res.resolved_def, res.reached_fixedpoint) 305 (res.resolved_def, res.reached_fixedpoint)
@@ -477,6 +478,7 @@ where
477 ResolveMode::Other, 478 ResolveMode::Other,
478 *module_id, 479 *module_id,
479 path, 480 path,
481 BuiltinShadowMode::Module,
480 ); 482 );
481 483
482 if let Some(def) = resolved_res.resolved_def.take_macros() { 484 if let Some(def) = resolved_res.resolved_def.take_macros() {
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index b72c55bd1..42a75226b 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -16,7 +16,7 @@ use test_utils::tested_by;
16 16
17use crate::{ 17use crate::{
18 db::DefDatabase, 18 db::DefDatabase,
19 nameres::CrateDefMap, 19 nameres::{BuiltinShadowMode, CrateDefMap},
20 path::{Path, PathKind}, 20 path::{Path, PathKind},
21 per_ns::PerNs, 21 per_ns::PerNs,
22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
@@ -68,7 +68,17 @@ impl CrateDefMap {
68 mode: ResolveMode, 68 mode: ResolveMode,
69 original_module: LocalModuleId, 69 original_module: LocalModuleId,
70 path: &Path, 70 path: &Path,
71 shadow: BuiltinShadowMode,
71 ) -> ResolvePathResult { 72 ) -> ResolvePathResult {
73 // if it is not the last segment, we prefer the module to the builtin
74 let prefer_module = |index| {
75 if index == path.segments.len() - 1 {
76 shadow
77 } else {
78 BuiltinShadowMode::Module
79 }
80 };
81
72 let mut segments = path.segments.iter().enumerate(); 82 let mut segments = path.segments.iter().enumerate();
73 let mut curr_per_ns: PerNs = match path.kind { 83 let mut curr_per_ns: PerNs = match path.kind {
74 PathKind::DollarCrate(krate) => { 84 PathKind::DollarCrate(krate) => {
@@ -96,20 +106,20 @@ impl CrateDefMap {
96 if self.edition == Edition::Edition2015 106 if self.edition == Edition::Edition2015
97 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => 107 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
98 { 108 {
99 let segment = match segments.next() { 109 let (idx, segment) = match segments.next() {
100 Some((_, segment)) => segment, 110 Some((idx, segment)) => (idx, segment),
101 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 111 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
102 }; 112 };
103 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); 113 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
104 self.resolve_name_in_crate_root_or_extern_prelude(&segment.name) 114 self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx))
105 } 115 }
106 PathKind::Plain => { 116 PathKind::Plain => {
107 let segment = match segments.next() { 117 let (idx, segment) = match segments.next() {
108 Some((_, segment)) => segment, 118 Some((idx, segment)) => (idx, segment),
109 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 119 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
110 }; 120 };
111 log::debug!("resolving {:?} in module", segment); 121 log::debug!("resolving {:?} in module", segment);
112 self.resolve_name_in_module(db, original_module, &segment.name) 122 self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx))
113 } 123 }
114 PathKind::Super => { 124 PathKind::Super => {
115 if let Some(p) = self.modules[original_module].parent { 125 if let Some(p) = self.modules[original_module].parent {
@@ -160,7 +170,7 @@ impl CrateDefMap {
160 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 170 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
161 log::debug!("resolving {:?} in other crate", path); 171 log::debug!("resolving {:?} in other crate", path);
162 let defp_map = db.crate_def_map(module.krate); 172 let defp_map = db.crate_def_map(module.krate);
163 let (def, s) = defp_map.resolve_path(db, module.local_id, &path); 173 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
164 return ResolvePathResult::with( 174 return ResolvePathResult::with(
165 def, 175 def,
166 ReachedFixedPoint::Yes, 176 ReachedFixedPoint::Yes,
@@ -169,7 +179,7 @@ impl CrateDefMap {
169 } 179 }
170 180
171 // Since it is a qualified path here, it should not contains legacy macros 181 // Since it is a qualified path here, it should not contains legacy macros
172 match self[module.local_id].scope.get(&segment.name) { 182 match self[module.local_id].scope.get(&segment.name, prefer_module(i)) {
173 Some(res) => res.def, 183 Some(res) => res.def,
174 _ => { 184 _ => {
175 log::debug!("path segment {:?} not found", segment.name); 185 log::debug!("path segment {:?} not found", segment.name);
@@ -212,6 +222,7 @@ impl CrateDefMap {
212 } 222 }
213 }; 223 };
214 } 224 }
225
215 ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) 226 ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
216 } 227 }
217 228
@@ -220,6 +231,7 @@ impl CrateDefMap {
220 db: &impl DefDatabase, 231 db: &impl DefDatabase,
221 module: LocalModuleId, 232 module: LocalModuleId,
222 name: &Name, 233 name: &Name,
234 shadow: BuiltinShadowMode,
223 ) -> PerNs { 235 ) -> PerNs {
224 // Resolve in: 236 // Resolve in:
225 // - legacy scope of macro 237 // - legacy scope of macro
@@ -228,23 +240,33 @@ impl CrateDefMap {
228 // - std prelude 240 // - std prelude
229 let from_legacy_macro = 241 let from_legacy_macro =
230 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); 242 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros);
231 let from_scope = self[module].scope.get(name).map_or_else(PerNs::none, |res| res.def); 243 let from_scope =
244 self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
232 let from_extern_prelude = 245 let from_extern_prelude =
233 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 246 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
234 let from_prelude = self.resolve_in_prelude(db, name); 247 let from_prelude = self.resolve_in_prelude(db, name, shadow);
235 248
236 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) 249 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude)
237 } 250 }
238 251
239 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { 252 fn resolve_name_in_crate_root_or_extern_prelude(
253 &self,
254 name: &Name,
255 shadow: BuiltinShadowMode,
256 ) -> PerNs {
240 let from_crate_root = 257 let from_crate_root =
241 self[self.root].scope.get(name).map_or_else(PerNs::none, |res| res.def); 258 self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
242 let from_extern_prelude = self.resolve_name_in_extern_prelude(name); 259 let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
243 260
244 from_crate_root.or(from_extern_prelude) 261 from_crate_root.or(from_extern_prelude)
245 } 262 }
246 263
247 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { 264 fn resolve_in_prelude(
265 &self,
266 db: &impl DefDatabase,
267 name: &Name,
268 shadow: BuiltinShadowMode,
269 ) -> PerNs {
248 if let Some(prelude) = self.prelude { 270 if let Some(prelude) = self.prelude {
249 let keep; 271 let keep;
250 let def_map = if prelude.krate == self.krate { 272 let def_map = if prelude.krate == self.krate {
@@ -254,7 +276,10 @@ impl CrateDefMap {
254 keep = db.crate_def_map(prelude.krate); 276 keep = db.crate_def_map(prelude.krate);
255 &keep 277 &keep
256 }; 278 };
257 def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) 279 def_map[prelude.local_id]
280 .scope
281 .get(name, shadow)
282 .map_or_else(PerNs::none, |res| res.def)
258 } else { 283 } else {
259 PerNs::none() 284 PerNs::none()
260 } 285 }
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/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 0847f6dcf..7d4df222e 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -14,7 +14,7 @@ use crate::{
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::CrateDefMap, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
@@ -91,7 +91,7 @@ pub enum ValueNs {
91impl Resolver { 91impl Resolver {
92 /// Resolve known trait from std, like `std::futures::Future` 92 /// Resolve known trait from std, like `std::futures::Future`
93 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> { 93 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> {
94 let res = self.resolve_module_path(db, path).take_types()?; 94 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
95 match res { 95 match res {
96 ModuleDefId::TraitId(it) => Some(it), 96 ModuleDefId::TraitId(it) => Some(it),
97 _ => None, 97 _ => None,
@@ -100,7 +100,7 @@ impl Resolver {
100 100
101 /// Resolve known struct from std, like `std::boxed::Box` 101 /// Resolve known struct from std, like `std::boxed::Box`
102 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> { 102 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> {
103 let res = self.resolve_module_path(db, path).take_types()?; 103 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
104 match res { 104 match res {
105 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), 105 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
106 _ => None, 106 _ => None,
@@ -109,26 +109,34 @@ impl Resolver {
109 109
110 /// Resolve known enum from std, like `std::result::Result` 110 /// Resolve known enum from std, like `std::result::Result`
111 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> { 111 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> {
112 let res = self.resolve_module_path(db, path).take_types()?; 112 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
113 match res { 113 match res {
114 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), 114 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
115 _ => None, 115 _ => None,
116 } 116 }
117 } 117 }
118 118
119 /// pub only for source-binder 119 fn resolve_module_path(
120 pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs { 120 &self,
121 db: &impl DefDatabase,
122 path: &Path,
123 shadow: BuiltinShadowMode,
124 ) -> PerNs {
121 let (item_map, module) = match self.module() { 125 let (item_map, module) = match self.module() {
122 Some(it) => it, 126 Some(it) => it,
123 None => return PerNs::none(), 127 None => return PerNs::none(),
124 }; 128 };
125 let (module_res, segment_index) = item_map.resolve_path(db, module, path); 129 let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
126 if segment_index.is_some() { 130 if segment_index.is_some() {
127 return PerNs::none(); 131 return PerNs::none();
128 } 132 }
129 module_res 133 module_res
130 } 134 }
131 135
136 pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &Path) -> PerNs {
137 self.resolve_module_path(db, path, BuiltinShadowMode::Module)
138 }
139
132 pub fn resolve_path_in_type_ns( 140 pub fn resolve_path_in_type_ns(
133 &self, 141 &self,
134 db: &impl DefDatabase, 142 db: &impl DefDatabase,
@@ -163,7 +171,12 @@ impl Resolver {
163 } 171 }
164 } 172 }
165 Scope::ModuleScope(m) => { 173 Scope::ModuleScope(m) => {
166 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); 174 let (module_def, idx) = m.crate_def_map.resolve_path(
175 db,
176 m.module_id,
177 path,
178 BuiltinShadowMode::Other,
179 );
167 let res = match module_def.take_types()? { 180 let res = match module_def.take_types()? {
168 ModuleDefId::AdtId(it) => TypeNs::AdtId(it), 181 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
169 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), 182 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
@@ -256,7 +269,12 @@ impl Resolver {
256 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, 269 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue,
257 270
258 Scope::ModuleScope(m) => { 271 Scope::ModuleScope(m) => {
259 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); 272 let (module_def, idx) = m.crate_def_map.resolve_path(
273 db,
274 m.module_id,
275 path,
276 BuiltinShadowMode::Other,
277 );
260 return match idx { 278 return match idx {
261 None => { 279 None => {
262 let value = match module_def.take_values()? { 280 let value = match module_def.take_values()? {
@@ -310,7 +328,7 @@ impl Resolver {
310 328
311 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 329 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
312 let (item_map, module) = self.module()?; 330 let (item_map, module) = self.module()?;
313 item_map.resolve_path(db, module, path).0.take_macros() 331 item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
314 } 332 }
315 333
316 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 334 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
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}