diff options
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 48 |
2 files changed, 62 insertions, 8 deletions
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index df87f520f..7e6e48ae0 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -8,7 +8,7 @@ use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | |||
8 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | SourceItemId, Path, ModuleSource, Name, | 11 | SourceItemId, Path, PathKind, ModuleSource, Name, |
12 | HirFileId, MacroCallLoc, AsName, PerNs, Function, | 12 | HirFileId, MacroCallLoc, AsName, PerNs, Function, |
13 | ModuleDef, Module, Struct, Enum, Const, Static, Trait, Type, | 13 | ModuleDef, Module, Struct, Enum, Const, Static, Trait, Type, |
14 | ids::LocationCtx, PersistentHirDatabase, | 14 | ids::LocationCtx, PersistentHirDatabase, |
@@ -23,6 +23,7 @@ pub(super) struct ImportData { | |||
23 | pub(super) path: Path, | 23 | pub(super) path: Path, |
24 | pub(super) alias: Option<Name>, | 24 | pub(super) alias: Option<Name>, |
25 | pub(super) is_glob: bool, | 25 | pub(super) is_glob: bool, |
26 | pub(super) is_extern_crate: bool, | ||
26 | } | 27 | } |
27 | 28 | ||
28 | /// A set of items and imports declared inside a module, without relation to | 29 | /// A set of items and imports declared inside a module, without relation to |
@@ -186,8 +187,22 @@ impl LoweredModule { | |||
186 | ast::ModuleItemKind::UseItem(it) => { | 187 | ast::ModuleItemKind::UseItem(it) => { |
187 | self.add_use_item(source_map, it); | 188 | self.add_use_item(source_map, it); |
188 | } | 189 | } |
189 | ast::ModuleItemKind::ExternCrateItem(_) => { | 190 | ast::ModuleItemKind::ExternCrateItem(it) => { |
190 | // TODO | 191 | // Lower `extern crate x` to `use ::x`. This is kind of cheating |
192 | // and only works if we always interpret absolute paths in the | ||
193 | // 2018 style; otherwise `::x` could also refer to a module in | ||
194 | // the crate root. | ||
195 | if let Some(name_ref) = it.name_ref() { | ||
196 | let mut path = Path::from_name_ref(name_ref); | ||
197 | path.kind = PathKind::Abs; | ||
198 | let alias = it.alias().and_then(|a| a.name()).map(AsName::as_name); | ||
199 | self.imports.alloc(ImportData { | ||
200 | path, | ||
201 | alias, | ||
202 | is_glob: false, | ||
203 | is_extern_crate: true, | ||
204 | }); | ||
205 | } | ||
191 | } | 206 | } |
192 | ast::ModuleItemKind::ConstDef(it) => { | 207 | ast::ModuleItemKind::ConstDef(it) => { |
193 | if let Some(name) = it.name() { | 208 | if let Some(name) = it.name() { |
@@ -215,6 +230,7 @@ impl LoweredModule { | |||
215 | path, | 230 | path, |
216 | alias, | 231 | alias, |
217 | is_glob: segment.is_none(), | 232 | is_glob: segment.is_none(), |
233 | is_extern_crate: false, | ||
218 | }); | 234 | }); |
219 | if let Some(segment) = segment { | 235 | if let Some(segment) = segment { |
220 | source_map.insert(import, segment) | 236 | source_map.insert(import, segment) |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 81c8a4f12..0654dbaa1 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -329,7 +329,49 @@ fn item_map_across_crates() { | |||
329 | module.module_id, | 329 | module.module_id, |
330 | " | 330 | " |
331 | Baz: t v | 331 | Baz: t v |
332 | test_crate: t | 332 | ", |
333 | ); | ||
334 | } | ||
335 | |||
336 | #[test] | ||
337 | fn extern_crate_rename() { | ||
338 | let (mut db, sr) = MockDatabase::with_files( | ||
339 | " | ||
340 | //- /main.rs | ||
341 | extern crate alloc as alloc_crate; | ||
342 | |||
343 | mod alloc; | ||
344 | mod sync; | ||
345 | |||
346 | //- /sync.rs | ||
347 | use alloc_crate::Arc; | ||
348 | |||
349 | //- /lib.rs | ||
350 | struct Arc; | ||
351 | ", | ||
352 | ); | ||
353 | let main_id = sr.files[RelativePath::new("/main.rs")]; | ||
354 | let sync_id = sr.files[RelativePath::new("/sync.rs")]; | ||
355 | let lib_id = sr.files[RelativePath::new("/lib.rs")]; | ||
356 | |||
357 | let mut crate_graph = CrateGraph::default(); | ||
358 | let main_crate = crate_graph.add_crate_root(main_id); | ||
359 | let lib_crate = crate_graph.add_crate_root(lib_id); | ||
360 | crate_graph | ||
361 | .add_dep(main_crate, "alloc".into(), lib_crate) | ||
362 | .unwrap(); | ||
363 | |||
364 | db.set_crate_graph(Arc::new(crate_graph)); | ||
365 | |||
366 | let module = crate::source_binder::module_from_file_id(&db, sync_id).unwrap(); | ||
367 | let krate = module.krate(&db).unwrap(); | ||
368 | let item_map = db.item_map(krate); | ||
369 | |||
370 | check_module_item_map( | ||
371 | &item_map, | ||
372 | module.module_id, | ||
373 | " | ||
374 | Arc: t v | ||
333 | ", | 375 | ", |
334 | ); | 376 | ); |
335 | } | 377 | } |
@@ -361,8 +403,6 @@ fn import_across_source_roots() { | |||
361 | 403 | ||
362 | let main_id = sr2.files[RelativePath::new("/main.rs")]; | 404 | let main_id = sr2.files[RelativePath::new("/main.rs")]; |
363 | 405 | ||
364 | eprintln!("lib = {:?}, main = {:?}", lib_id, main_id); | ||
365 | |||
366 | let mut crate_graph = CrateGraph::default(); | 406 | let mut crate_graph = CrateGraph::default(); |
367 | let main_crate = crate_graph.add_crate_root(main_id); | 407 | let main_crate = crate_graph.add_crate_root(main_id); |
368 | let lib_crate = crate_graph.add_crate_root(lib_id); | 408 | let lib_crate = crate_graph.add_crate_root(lib_id); |
@@ -381,7 +421,6 @@ fn import_across_source_roots() { | |||
381 | module.module_id, | 421 | module.module_id, |
382 | " | 422 | " |
383 | C: t v | 423 | C: t v |
384 | test_crate: t | ||
385 | ", | 424 | ", |
386 | ); | 425 | ); |
387 | } | 426 | } |
@@ -423,7 +462,6 @@ fn reexport_across_crates() { | |||
423 | module.module_id, | 462 | module.module_id, |
424 | " | 463 | " |
425 | Baz: t v | 464 | Baz: t v |
426 | test_crate: t | ||
427 | ", | 465 | ", |
428 | ); | 466 | ); |
429 | } | 467 | } |