diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-13 20:14:39 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-13 20:14:39 +0000 |
commit | cb4327b3a9f0858235dc20b7c5c7e25c6c330aab (patch) | |
tree | 489b3497b2762dcabf60d2674031585431e16959 /crates/ra_db/src | |
parent | 65266c644a31e6b321e5afb3c5a2ee75be76cb0c (diff) | |
parent | 911e32bca9b73e66eceb6bbee3768c82e94597d5 (diff) |
Merge #816
816: Prelude & Edition 2015 import resolution r=matklad a=flodiebold
I implemented the prelude import, but it turned out to be useless without being able to resolve any of the imports in the prelude :sweat_smile: So I had to add some edition handling and handle 2015-style imports (at least the simplified scheme proposed in rust-lang/rust#57745). So now finally `Option` resolves :smile:
One remaining problem is that we don't actually know the edition for sysroot crates. They're currently hardcoded to 2015, but there's already a bunch of PRs upgrading the editions of various rustc crates, so we'll have to detect the edition somehow, or just change the hardcoding to 2018 later, I guess...
~Also currently missing is completion for prelude names, though that shouldn't be hard to add. And `Vec` still doesn't resolve, so I need to look into that.~
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r-- | crates/ra_db/src/input.rs | 44 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 2 |
2 files changed, 33 insertions, 13 deletions
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 8decc65c5..e45a510b3 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -56,15 +56,31 @@ pub struct CyclicDependencies; | |||
56 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 56 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
57 | pub struct CrateId(pub u32); | 57 | pub struct CrateId(pub u32); |
58 | 58 | ||
59 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
60 | pub enum Edition { | ||
61 | Edition2018, | ||
62 | Edition2015, | ||
63 | } | ||
64 | |||
65 | impl Edition { | ||
66 | pub fn from_string(s: &str) -> Edition { | ||
67 | match s { | ||
68 | "2015" => Edition::Edition2015, | ||
69 | "2018" | _ => Edition::Edition2018, | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
59 | #[derive(Debug, Clone, PartialEq, Eq)] | 74 | #[derive(Debug, Clone, PartialEq, Eq)] |
60 | struct CrateData { | 75 | struct CrateData { |
61 | file_id: FileId, | 76 | file_id: FileId, |
77 | edition: Edition, | ||
62 | dependencies: Vec<Dependency>, | 78 | dependencies: Vec<Dependency>, |
63 | } | 79 | } |
64 | 80 | ||
65 | impl CrateData { | 81 | impl CrateData { |
66 | fn new(file_id: FileId) -> CrateData { | 82 | fn new(file_id: FileId, edition: Edition) -> CrateData { |
67 | CrateData { file_id, dependencies: Vec::new() } | 83 | CrateData { file_id, edition, dependencies: Vec::new() } |
68 | } | 84 | } |
69 | 85 | ||
70 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { | 86 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
@@ -85,9 +101,9 @@ impl Dependency { | |||
85 | } | 101 | } |
86 | 102 | ||
87 | impl CrateGraph { | 103 | impl CrateGraph { |
88 | pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId { | 104 | pub fn add_crate_root(&mut self, file_id: FileId, edition: Edition) -> CrateId { |
89 | let crate_id = CrateId(self.arena.len() as u32); | 105 | let crate_id = CrateId(self.arena.len() as u32); |
90 | let prev = self.arena.insert(crate_id, CrateData::new(file_id)); | 106 | let prev = self.arena.insert(crate_id, CrateData::new(file_id, edition)); |
91 | assert!(prev.is_none()); | 107 | assert!(prev.is_none()); |
92 | crate_id | 108 | crate_id |
93 | } | 109 | } |
@@ -112,6 +128,10 @@ impl CrateGraph { | |||
112 | self.arena[&crate_id].file_id | 128 | self.arena[&crate_id].file_id |
113 | } | 129 | } |
114 | 130 | ||
131 | pub fn edition(&self, crate_id: CrateId) -> Edition { | ||
132 | self.arena[&crate_id].edition | ||
133 | } | ||
134 | |||
115 | // TODO: this only finds one crate with the given root; we could have multiple | 135 | // TODO: this only finds one crate with the given root; we could have multiple |
116 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | 136 | pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { |
117 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; | 137 | let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?; |
@@ -159,14 +179,14 @@ impl CrateGraph { | |||
159 | 179 | ||
160 | #[cfg(test)] | 180 | #[cfg(test)] |
161 | mod tests { | 181 | mod tests { |
162 | use super::{CrateGraph, FileId, SmolStr}; | 182 | use super::{CrateGraph, FileId, SmolStr, Edition::Edition2018}; |
163 | 183 | ||
164 | #[test] | 184 | #[test] |
165 | fn it_should_painc_because_of_cycle_dependencies() { | 185 | fn it_should_panic_because_of_cycle_dependencies() { |
166 | let mut graph = CrateGraph::default(); | 186 | let mut graph = CrateGraph::default(); |
167 | let crate1 = graph.add_crate_root(FileId(1u32)); | 187 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018); |
168 | let crate2 = graph.add_crate_root(FileId(2u32)); | 188 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018); |
169 | let crate3 = graph.add_crate_root(FileId(3u32)); | 189 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018); |
170 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 190 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
171 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 191 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
172 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); | 192 | assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err()); |
@@ -175,9 +195,9 @@ mod tests { | |||
175 | #[test] | 195 | #[test] |
176 | fn it_works() { | 196 | fn it_works() { |
177 | let mut graph = CrateGraph::default(); | 197 | let mut graph = CrateGraph::default(); |
178 | let crate1 = graph.add_crate_root(FileId(1u32)); | 198 | let crate1 = graph.add_crate_root(FileId(1u32), Edition2018); |
179 | let crate2 = graph.add_crate_root(FileId(2u32)); | 199 | let crate2 = graph.add_crate_root(FileId(2u32), Edition2018); |
180 | let crate3 = graph.add_crate_root(FileId(3u32)); | 200 | let crate3 = graph.add_crate_root(FileId(3u32), Edition2018); |
181 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); | 201 | assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok()); |
182 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); | 202 | assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok()); |
183 | } | 203 | } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 31442713d..e006c6d27 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -14,7 +14,7 @@ pub use ::salsa as salsa; | |||
14 | pub use crate::{ | 14 | pub use crate::{ |
15 | cancellation::Canceled, | 15 | cancellation::Canceled, |
16 | input::{ | 16 | input::{ |
17 | FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, | 17 | FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition, |
18 | }, | 18 | }, |
19 | loc2id::LocationIntener, | 19 | loc2id::LocationIntener, |
20 | }; | 20 | }; |