diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-24 15:59:47 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-24 15:59:47 +0000 |
commit | b0581c2403f49c68738c039065fa2cfc41345738 (patch) | |
tree | 2a977c54f7203f3f11784b7ee7ece20fd3b7ef9e | |
parent | 775bd98e5cf7918acf0dd72009ac14cf758ed0ca (diff) | |
parent | 6a8b4f873aa42f3522d3a92384019272b6ccefd2 (diff) |
Merge #2381
2381: Add proc-macro crate type handling r=JasperDeSutter a=JasperDeSutter
Resolves the libproc_macro crate in crates that are the proc-macro type.
This doesn't seem the ideal implementation though, since the compiler still requires you to write `extern crate proc_macro;` (even in 2018 edition).
Co-authored-by: JasperDeSutter <[email protected]>
-rw-r--r-- | crates/ra_project_model/src/cargo_workspace.rs | 8 | ||||
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 17 | ||||
-rw-r--r-- | crates/ra_project_model/src/sysroot.rs | 6 |
3 files changed, 30 insertions, 1 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index c128e608d..351997dcd 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -54,11 +54,13 @@ struct TargetData { | |||
54 | name: String, | 54 | name: String, |
55 | root: PathBuf, | 55 | root: PathBuf, |
56 | kind: TargetKind, | 56 | kind: TargetKind, |
57 | is_proc_macro: bool, | ||
57 | } | 58 | } |
58 | 59 | ||
59 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 60 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
60 | pub enum TargetKind { | 61 | pub enum TargetKind { |
61 | Bin, | 62 | Bin, |
63 | /// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...). | ||
62 | Lib, | 64 | Lib, |
63 | Example, | 65 | Example, |
64 | Test, | 66 | Test, |
@@ -74,6 +76,7 @@ impl TargetKind { | |||
74 | "test" => TargetKind::Test, | 76 | "test" => TargetKind::Test, |
75 | "bench" => TargetKind::Bench, | 77 | "bench" => TargetKind::Bench, |
76 | "example" => TargetKind::Example, | 78 | "example" => TargetKind::Example, |
79 | "proc-macro" => TargetKind::Lib, | ||
77 | _ if kind.contains("lib") => TargetKind::Lib, | 80 | _ if kind.contains("lib") => TargetKind::Lib, |
78 | _ => continue, | 81 | _ => continue, |
79 | }; | 82 | }; |
@@ -123,6 +126,9 @@ impl Target { | |||
123 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { | 126 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { |
124 | ws.targets[self].kind | 127 | ws.targets[self].kind |
125 | } | 128 | } |
129 | pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool { | ||
130 | ws.targets[self].is_proc_macro | ||
131 | } | ||
126 | } | 132 | } |
127 | 133 | ||
128 | impl CargoWorkspace { | 134 | impl CargoWorkspace { |
@@ -155,11 +161,13 @@ impl CargoWorkspace { | |||
155 | let pkg_data = &mut packages[pkg]; | 161 | let pkg_data = &mut packages[pkg]; |
156 | pkg_by_id.insert(id, pkg); | 162 | pkg_by_id.insert(id, pkg); |
157 | for meta_tgt in meta_pkg.targets { | 163 | for meta_tgt in meta_pkg.targets { |
164 | let is_proc_macro = meta_tgt.kind.as_slice() == &["proc-macro"]; | ||
158 | let tgt = targets.alloc(TargetData { | 165 | let tgt = targets.alloc(TargetData { |
159 | pkg, | 166 | pkg, |
160 | name: meta_tgt.name, | 167 | name: meta_tgt.name, |
161 | root: meta_tgt.src_path.clone(), | 168 | root: meta_tgt.src_path.clone(), |
162 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | 169 | kind: TargetKind::new(meta_tgt.kind.as_slice()), |
170 | is_proc_macro, | ||
163 | }); | 171 | }); |
164 | pkg_data.targets.push(tgt); | 172 | pkg_data.targets.push(tgt); |
165 | } | 173 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 638ca2f8b..55ff4d6ef 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -211,6 +211,8 @@ impl ProjectWorkspace { | |||
211 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); | 211 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); |
212 | let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied()); | 212 | let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied()); |
213 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); | 213 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); |
214 | let libproc_macro = | ||
215 | sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); | ||
214 | 216 | ||
215 | let mut pkg_to_lib_crate = FxHashMap::default(); | 217 | let mut pkg_to_lib_crate = FxHashMap::default(); |
216 | let mut pkg_crates = FxHashMap::default(); | 218 | let mut pkg_crates = FxHashMap::default(); |
@@ -237,6 +239,21 @@ impl ProjectWorkspace { | |||
237 | lib_tgt = Some(crate_id); | 239 | lib_tgt = Some(crate_id); |
238 | pkg_to_lib_crate.insert(pkg, crate_id); | 240 | pkg_to_lib_crate.insert(pkg, crate_id); |
239 | } | 241 | } |
242 | if tgt.is_proc_macro(&cargo) { | ||
243 | if let Some(proc_macro) = libproc_macro { | ||
244 | if let Err(_) = crate_graph.add_dep( | ||
245 | crate_id, | ||
246 | "proc_macro".into(), | ||
247 | proc_macro, | ||
248 | ) { | ||
249 | log::error!( | ||
250 | "cyclic dependency on proc_macro for {}", | ||
251 | pkg.name(&cargo) | ||
252 | ) | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
240 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); | 257 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); |
241 | } | 258 | } |
242 | } | 259 | } |
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index bec9439d7..10ca391b6 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -39,6 +39,10 @@ impl Sysroot { | |||
39 | self.by_name("std") | 39 | self.by_name("std") |
40 | } | 40 | } |
41 | 41 | ||
42 | pub fn proc_macro(&self) -> Option<SysrootCrate> { | ||
43 | self.by_name("proc_macro") | ||
44 | } | ||
45 | |||
42 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a { | 46 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a { |
43 | self.crates.iter().map(|(id, _data)| id) | 47 | self.crates.iter().map(|(id, _data)| id) |
44 | } | 48 | } |
@@ -74,7 +78,7 @@ impl Sysroot { | |||
74 | } | 78 | } |
75 | } | 79 | } |
76 | if let Some(alloc) = sysroot.by_name("alloc") { | 80 | if let Some(alloc) = sysroot.by_name("alloc") { |
77 | if let Some(core) = sysroot.by_name("core") { | 81 | if let Some(core) = sysroot.core() { |
78 | sysroot.crates[alloc].deps.push(core); | 82 | sysroot.crates[alloc].deps.push(core); |
79 | } | 83 | } |
80 | } | 84 | } |