mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
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 <jasper.desutter@gmail.com>
This commit is contained in:
commit
b0581c2403
3 changed files with 30 additions and 1 deletions
|
@ -54,11 +54,13 @@ struct TargetData {
|
||||||
name: String,
|
name: String,
|
||||||
root: PathBuf,
|
root: PathBuf,
|
||||||
kind: TargetKind,
|
kind: TargetKind,
|
||||||
|
is_proc_macro: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum TargetKind {
|
pub enum TargetKind {
|
||||||
Bin,
|
Bin,
|
||||||
|
/// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...).
|
||||||
Lib,
|
Lib,
|
||||||
Example,
|
Example,
|
||||||
Test,
|
Test,
|
||||||
|
@ -74,6 +76,7 @@ impl TargetKind {
|
||||||
"test" => TargetKind::Test,
|
"test" => TargetKind::Test,
|
||||||
"bench" => TargetKind::Bench,
|
"bench" => TargetKind::Bench,
|
||||||
"example" => TargetKind::Example,
|
"example" => TargetKind::Example,
|
||||||
|
"proc-macro" => TargetKind::Lib,
|
||||||
_ if kind.contains("lib") => TargetKind::Lib,
|
_ if kind.contains("lib") => TargetKind::Lib,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
@ -123,6 +126,9 @@ impl Target {
|
||||||
pub fn kind(self, ws: &CargoWorkspace) -> TargetKind {
|
pub fn kind(self, ws: &CargoWorkspace) -> TargetKind {
|
||||||
ws.targets[self].kind
|
ws.targets[self].kind
|
||||||
}
|
}
|
||||||
|
pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool {
|
||||||
|
ws.targets[self].is_proc_macro
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CargoWorkspace {
|
impl CargoWorkspace {
|
||||||
|
@ -155,11 +161,13 @@ impl CargoWorkspace {
|
||||||
let pkg_data = &mut packages[pkg];
|
let pkg_data = &mut packages[pkg];
|
||||||
pkg_by_id.insert(id, pkg);
|
pkg_by_id.insert(id, pkg);
|
||||||
for meta_tgt in meta_pkg.targets {
|
for meta_tgt in meta_pkg.targets {
|
||||||
|
let is_proc_macro = meta_tgt.kind.as_slice() == &["proc-macro"];
|
||||||
let tgt = targets.alloc(TargetData {
|
let tgt = targets.alloc(TargetData {
|
||||||
pkg,
|
pkg,
|
||||||
name: meta_tgt.name,
|
name: meta_tgt.name,
|
||||||
root: meta_tgt.src_path.clone(),
|
root: meta_tgt.src_path.clone(),
|
||||||
kind: TargetKind::new(meta_tgt.kind.as_slice()),
|
kind: TargetKind::new(meta_tgt.kind.as_slice()),
|
||||||
|
is_proc_macro,
|
||||||
});
|
});
|
||||||
pkg_data.targets.push(tgt);
|
pkg_data.targets.push(tgt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,8 @@ impl ProjectWorkspace {
|
||||||
let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
|
let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied());
|
||||||
let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied());
|
let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied());
|
||||||
let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
|
let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied());
|
||||||
|
let libproc_macro =
|
||||||
|
sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
|
||||||
|
|
||||||
let mut pkg_to_lib_crate = FxHashMap::default();
|
let mut pkg_to_lib_crate = FxHashMap::default();
|
||||||
let mut pkg_crates = FxHashMap::default();
|
let mut pkg_crates = FxHashMap::default();
|
||||||
|
@ -237,6 +239,21 @@ impl ProjectWorkspace {
|
||||||
lib_tgt = Some(crate_id);
|
lib_tgt = Some(crate_id);
|
||||||
pkg_to_lib_crate.insert(pkg, crate_id);
|
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||||
}
|
}
|
||||||
|
if tgt.is_proc_macro(&cargo) {
|
||||||
|
if let Some(proc_macro) = libproc_macro {
|
||||||
|
if let Err(_) = crate_graph.add_dep(
|
||||||
|
crate_id,
|
||||||
|
"proc_macro".into(),
|
||||||
|
proc_macro,
|
||||||
|
) {
|
||||||
|
log::error!(
|
||||||
|
"cyclic dependency on proc_macro for {}",
|
||||||
|
pkg.name(&cargo)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
|
pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,10 @@ impl Sysroot {
|
||||||
self.by_name("std")
|
self.by_name("std")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn proc_macro(&self) -> Option<SysrootCrate> {
|
||||||
|
self.by_name("proc_macro")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a {
|
pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a {
|
||||||
self.crates.iter().map(|(id, _data)| id)
|
self.crates.iter().map(|(id, _data)| id)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +78,7 @@ impl Sysroot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(alloc) = sysroot.by_name("alloc") {
|
if let Some(alloc) = sysroot.by_name("alloc") {
|
||||||
if let Some(core) = sysroot.by_name("core") {
|
if let Some(core) = sysroot.core() {
|
||||||
sysroot.crates[alloc].deps.push(core);
|
sysroot.crates[alloc].deps.push(core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue