diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-05 07:53:08 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-05 07:53:08 +0000 |
commit | 4d4c46aff8f9a7ce8c2f91fbe6c7c363f5d3e08c (patch) | |
tree | 90473c4a67ac70ee40fde54a25b11d7768c41593 /crates/ra_hir/src/nameres/lower.rs | |
parent | 94d5d0d7e893a50bdd22ce4366ca15f083218d22 (diff) | |
parent | de4c5e381fb1adc25143dcd67af6c87f6d9789ae (diff) |
Merge #742
742: Extern crate r=matklad a=flodiebold
This implements `extern crate` declarations by lowering them to (absolute) imports, and adds support for absolute paths. It also extracts the extern prelude from the per-module item map, and handles the special case of extern crates in the crate root adding to the extern prelude.
This means we finally resolve `Arc`, so it fixes #523 :smile:
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/nameres/lower.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/lower.rs | 22 |
1 files changed, 19 insertions, 3 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) |