diff options
Diffstat (limited to 'crates/ra_hir_def/src/nameres.rs')
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 45 |
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; | |||
58 | use std::sync::Arc; | 58 | use std::sync::Arc; |
59 | 59 | ||
60 | use hir_expand::{ | 60 | use 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 | }; |
64 | use once_cell::sync::Lazy; | 64 | use once_cell::sync::Lazy; |
65 | use ra_arena::Arena; | 65 | use 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)] | ||
154 | pub 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. |
154 | impl ModuleScope { | 163 | impl 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 | }) |