Skip to content

Commit f94e112

Browse files
bors[bot]flodiebold
andcommitted
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 😅 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 😄 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]>
2 parents 65266c6 + e99034d commit f94e112

File tree

18 files changed

+403
-60
lines changed

18 files changed

+403
-60
lines changed

crates/ra_db/src/input.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,31 @@ pub struct CyclicDependencies;
5656
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5757
pub struct CrateId(pub u32);
5858

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+
5974
#[derive(Debug, Clone, PartialEq, Eq)]
6075
struct CrateData {
6176
file_id: FileId,
77+
edition: Edition,
6278
dependencies: Vec<Dependency>,
6379
}
6480

6581
impl CrateData {
66-
fn new(file_id: FileId) -> CrateData {
67-
CrateData { file_id, dependencies: Vec::new() }
82+
fn new(file_id: FileId, edition: Edition) -> CrateData {
83+
CrateData { file_id, edition, dependencies: Vec::new() }
6884
}
6985

7086
fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
@@ -85,9 +101,9 @@ impl Dependency {
85101
}
86102

87103
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 {
89105
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));
91107
assert!(prev.is_none());
92108
crate_id
93109
}
@@ -112,6 +128,10 @@ impl CrateGraph {
112128
self.arena[&crate_id].file_id
113129
}
114130

131+
pub fn edition(&self, crate_id: CrateId) -> Edition {
132+
self.arena[&crate_id].edition
133+
}
134+
115135
// TODO: this only finds one crate with the given root; we could have multiple
116136
pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
117137
let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
@@ -159,14 +179,14 @@ impl CrateGraph {
159179

160180
#[cfg(test)]
161181
mod tests {
162-
use super::{CrateGraph, FileId, SmolStr};
182+
use super::{CrateGraph, FileId, SmolStr, Edition::Edition2018};
163183

164184
#[test]
165-
fn it_should_painc_because_of_cycle_dependencies() {
185+
fn it_should_panic_because_of_cycle_dependencies() {
166186
let mut graph = CrateGraph::default();
167-
let crate1 = graph.add_crate_root(FileId(1u32));
168-
let crate2 = graph.add_crate_root(FileId(2u32));
169-
let crate3 = graph.add_crate_root(FileId(3u32));
187+
let crate1 = graph.add_crate_root(FileId(1u32), Edition2018);
188+
let crate2 = graph.add_crate_root(FileId(2u32), Edition2018);
189+
let crate3 = graph.add_crate_root(FileId(3u32), Edition2018);
170190
assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok());
171191
assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok());
172192
assert!(graph.add_dep(crate3, SmolStr::new("crate1"), crate1).is_err());
@@ -175,9 +195,9 @@ mod tests {
175195
#[test]
176196
fn it_works() {
177197
let mut graph = CrateGraph::default();
178-
let crate1 = graph.add_crate_root(FileId(1u32));
179-
let crate2 = graph.add_crate_root(FileId(2u32));
180-
let crate3 = graph.add_crate_root(FileId(3u32));
198+
let crate1 = graph.add_crate_root(FileId(1u32), Edition2018);
199+
let crate2 = graph.add_crate_root(FileId(2u32), Edition2018);
200+
let crate3 = graph.add_crate_root(FileId(3u32), Edition2018);
181201
assert!(graph.add_dep(crate1, SmolStr::new("crate2"), crate2).is_ok());
182202
assert!(graph.add_dep(crate2, SmolStr::new("crate3"), crate3).is_ok());
183203
}

crates/ra_db/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use ::salsa as salsa;
1414
pub use crate::{
1515
cancellation::Canceled,
1616
input::{
17-
FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency,
17+
FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, Edition,
1818
},
1919
loc2id::LocationIntener,
2020
};

crates/ra_hir/src/code_model_api.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::sync::Arc;
22

33
use relative_path::RelativePathBuf;
4-
use ra_db::{CrateId, FileId, SourceRootId};
4+
use ra_db::{CrateId, FileId, SourceRootId, Edition};
55
use ra_syntax::{ast::self, TreeArc, SyntaxNode};
66

77
use crate::{
@@ -38,13 +38,20 @@ impl Crate {
3838
pub fn crate_id(&self) -> CrateId {
3939
self.crate_id
4040
}
41+
4142
pub fn dependencies(&self, db: &impl PersistentHirDatabase) -> Vec<CrateDependency> {
4243
self.dependencies_impl(db)
4344
}
45+
4446
pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> {
4547
self.root_module_impl(db)
4648
}
4749

50+
pub fn edition(&self, db: &impl PersistentHirDatabase) -> Edition {
51+
let crate_graph = db.crate_graph();
52+
crate_graph.edition(self.crate_id)
53+
}
54+
4855
// TODO: should this be in source_binder?
4956
pub fn source_root_crates(
5057
db: &impl PersistentHirDatabase,

crates/ra_hir/src/marks.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ test_utils::marks!(
66
type_var_resolves_to_int_var
77
glob_enum
88
glob_across_crates
9+
std_prelude
910
);

crates/ra_hir/src/mock.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{sync::Arc, panic};
33
use parking_lot::Mutex;
44
use ra_db::{
55
FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa,
6+
Edition,
67
};
78
use relative_path::RelativePathBuf;
89
use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset};
@@ -58,12 +59,12 @@ impl MockDatabase {
5859
pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) {
5960
let mut ids = FxHashMap::default();
6061
let mut crate_graph = CrateGraph::default();
61-
for (crate_name, (crate_root, _)) in graph.0.iter() {
62+
for (crate_name, (crate_root, edition, _)) in graph.0.iter() {
6263
let crate_root = self.file_id_of(&crate_root);
63-
let crate_id = crate_graph.add_crate_root(crate_root);
64+
let crate_id = crate_graph.add_crate_root(crate_root, *edition);
6465
ids.insert(crate_name, crate_id);
6566
}
66-
for (crate_name, (_, deps)) in graph.0.iter() {
67+
for (crate_name, (_, _, deps)) in graph.0.iter() {
6768
let from = ids[crate_name];
6869
for dep in deps {
6970
let to = ids[dep];
@@ -144,7 +145,7 @@ impl MockDatabase {
144145

145146
if is_crate_root {
146147
let mut crate_graph = CrateGraph::default();
147-
crate_graph.add_crate_root(file_id);
148+
crate_graph.add_crate_root(file_id, Edition::Edition2018);
148149
self.set_crate_graph(Arc::new(crate_graph));
149150
}
150151
file_id
@@ -232,16 +233,19 @@ impl MockDatabase {
232233
}
233234

234235
#[derive(Default)]
235-
pub struct CrateGraphFixture(pub FxHashMap<String, (String, Vec<String>)>);
236+
pub struct CrateGraphFixture(pub FxHashMap<String, (String, Edition, Vec<String>)>);
236237

237238
#[macro_export]
238239
macro_rules! crate_graph {
239-
($($crate_name:literal: ($crate_path:literal, [$($dep:literal),*]),)*) => {{
240+
($($crate_name:literal: ($crate_path:literal, $($edition:literal,)? [$($dep:literal),*]),)*) => {{
240241
let mut res = $crate::mock::CrateGraphFixture::default();
241242
$(
243+
#[allow(unused_mut, unused_assignments)]
244+
let mut edition = ra_db::Edition::Edition2018;
245+
$(edition = ra_db::Edition::from_string($edition);)?
242246
res.0.insert(
243247
$crate_name.to_string(),
244-
($crate_path.to_string(), vec![$($dep.to_string()),*])
248+
($crate_path.to_string(), edition, vec![$($dep.to_string()),*])
245249
);
246250
)*
247251
res

0 commit comments

Comments
 (0)