aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres.rs')
-rw-r--r--crates/ra_hir_def/src/nameres.rs45
1 files changed, 34 insertions, 11 deletions
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 })