Skip to content

Commit 988f1dd

Browse files
bors[bot]matklad
andauthored
Merge #3658
3658: More direct CargoWorkspace r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents d013a05 + fc230b9 commit 988f1dd

File tree

4 files changed

+84
-109
lines changed

4 files changed

+84
-109
lines changed

crates/ra_project_model/src/cargo_workspace.rs

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! FIXME: write short doc here
22
3-
use std::path::{Path, PathBuf};
3+
use std::{
4+
ops,
5+
path::{Path, PathBuf},
6+
};
47

58
use anyhow::{Context, Result};
69
use cargo_metadata::{CargoOpt, Message, MetadataCommand, PackageId};
@@ -24,6 +27,20 @@ pub struct CargoWorkspace {
2427
workspace_root: PathBuf,
2528
}
2629

30+
impl ops::Index<Package> for CargoWorkspace {
31+
type Output = PackageData;
32+
fn index(&self, index: Package) -> &PackageData {
33+
&self.packages[index]
34+
}
35+
}
36+
37+
impl ops::Index<Target> for CargoWorkspace {
38+
type Output = TargetData;
39+
fn index(&self, index: Target) -> &TargetData {
40+
&self.targets[index]
41+
}
42+
}
43+
2744
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
2845
#[serde(rename_all = "camelCase", default)]
2946
pub struct CargoFeatures {
@@ -61,15 +78,15 @@ pub struct Target(RawId);
6178
impl_arena_id!(Target);
6279

6380
#[derive(Debug, Clone)]
64-
struct PackageData {
65-
name: String,
66-
manifest: PathBuf,
67-
targets: Vec<Target>,
68-
is_member: bool,
69-
dependencies: Vec<PackageDependency>,
70-
edition: Edition,
71-
features: Vec<String>,
72-
out_dir: Option<PathBuf>,
81+
pub struct PackageData {
82+
pub name: String,
83+
pub manifest: PathBuf,
84+
pub targets: Vec<Target>,
85+
pub is_member: bool,
86+
pub dependencies: Vec<PackageDependency>,
87+
pub edition: Edition,
88+
pub features: Vec<String>,
89+
pub out_dir: Option<PathBuf>,
7390
}
7491

7592
#[derive(Debug, Clone)]
@@ -79,12 +96,12 @@ pub struct PackageDependency {
7996
}
8097

8198
#[derive(Debug, Clone)]
82-
struct TargetData {
83-
pkg: Package,
84-
name: String,
85-
root: PathBuf,
86-
kind: TargetKind,
87-
is_proc_macro: bool,
99+
pub struct TargetData {
100+
pub package: Package,
101+
pub name: String,
102+
pub root: PathBuf,
103+
pub kind: TargetKind,
104+
pub is_proc_macro: bool,
88105
}
89106

90107
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -115,52 +132,9 @@ impl TargetKind {
115132
}
116133
}
117134

118-
impl Package {
119-
pub fn name(self, ws: &CargoWorkspace) -> &str {
120-
ws.packages[self].name.as_str()
121-
}
122-
pub fn root(self, ws: &CargoWorkspace) -> &Path {
123-
ws.packages[self].manifest.parent().unwrap()
124-
}
125-
pub fn edition(self, ws: &CargoWorkspace) -> Edition {
126-
ws.packages[self].edition
127-
}
128-
pub fn features(self, ws: &CargoWorkspace) -> &[String] {
129-
&ws.packages[self].features
130-
}
131-
pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a {
132-
ws.packages[self].targets.iter().cloned()
133-
}
134-
#[allow(unused)]
135-
pub fn is_member(self, ws: &CargoWorkspace) -> bool {
136-
ws.packages[self].is_member
137-
}
138-
pub fn dependencies<'a>(
139-
self,
140-
ws: &'a CargoWorkspace,
141-
) -> impl Iterator<Item = &'a PackageDependency> + 'a {
142-
ws.packages[self].dependencies.iter()
143-
}
144-
pub fn out_dir(self, ws: &CargoWorkspace) -> Option<&Path> {
145-
ws.packages[self].out_dir.as_ref().map(PathBuf::as_path)
146-
}
147-
}
148-
149-
impl Target {
150-
pub fn package(self, ws: &CargoWorkspace) -> Package {
151-
ws.targets[self].pkg
152-
}
153-
pub fn name(self, ws: &CargoWorkspace) -> &str {
154-
ws.targets[self].name.as_str()
155-
}
156-
pub fn root(self, ws: &CargoWorkspace) -> &Path {
157-
ws.targets[self].root.as_path()
158-
}
159-
pub fn kind(self, ws: &CargoWorkspace) -> TargetKind {
160-
ws.targets[self].kind
161-
}
162-
pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool {
163-
ws.targets[self].is_proc_macro
135+
impl PackageData {
136+
pub fn root(&self) -> &Path {
137+
self.manifest.parent().unwrap()
164138
}
165139
}
166140

@@ -219,7 +193,7 @@ impl CargoWorkspace {
219193
for meta_tgt in meta_pkg.targets {
220194
let is_proc_macro = meta_tgt.kind.as_slice() == ["proc-macro"];
221195
let tgt = targets.alloc(TargetData {
222-
pkg,
196+
package: pkg,
223197
name: meta_tgt.name,
224198
root: meta_tgt.src_path.clone(),
225199
kind: TargetKind::new(meta_tgt.kind.as_slice()),
@@ -265,7 +239,10 @@ impl CargoWorkspace {
265239
}
266240

267241
pub fn target_by_root(&self, root: &Path) -> Option<Target> {
268-
self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next()
242+
self.packages()
243+
.filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root))
244+
.next()
245+
.copied()
269246
}
270247

271248
pub fn workspace_root(&self) -> &Path {

crates/ra_project_model/src/lib.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ impl ProjectWorkspace {
138138
ProjectWorkspace::Cargo { cargo, sysroot } => {
139139
let mut roots = Vec::with_capacity(cargo.packages().len() + sysroot.crates().len());
140140
for pkg in cargo.packages() {
141-
let root = pkg.root(&cargo).to_path_buf();
142-
let member = pkg.is_member(&cargo);
141+
let root = cargo[pkg].root().to_path_buf();
142+
let member = cargo[pkg].is_member;
143143
roots.push(PackageRoot::new(root, member));
144144
}
145145
for krate in sysroot.crates() {
146-
roots.push(PackageRoot::new(krate.root_dir(&sysroot).to_path_buf(), false))
146+
roots.push(PackageRoot::new(sysroot[krate].root_dir().to_path_buf(), false))
147147
}
148148
roots
149149
}
@@ -164,7 +164,7 @@ impl ProjectWorkspace {
164164
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
165165
let mut out_dirs = Vec::with_capacity(cargo.packages().len());
166166
for pkg in cargo.packages() {
167-
if let Some(out_dir) = pkg.out_dir(&cargo) {
167+
if let Some(out_dir) = &cargo[pkg].out_dir {
168168
out_dirs.push(out_dir.to_path_buf());
169169
}
170170
}
@@ -260,7 +260,7 @@ impl ProjectWorkspace {
260260
ProjectWorkspace::Cargo { cargo, sysroot } => {
261261
let mut sysroot_crates = FxHashMap::default();
262262
for krate in sysroot.crates() {
263-
if let Some(file_id) = load(krate.root(&sysroot)) {
263+
if let Some(file_id) = load(&sysroot[krate].root) {
264264
// Crates from sysroot have `cfg(test)` disabled
265265
let cfg_options = {
266266
let mut opts = default_cfg_options.clone();
@@ -274,7 +274,7 @@ impl ProjectWorkspace {
274274
file_id,
275275
Edition::Edition2018,
276276
Some(
277-
CrateName::new(krate.name(&sysroot))
277+
CrateName::new(&sysroot[krate].name)
278278
.expect("Sysroot crate names should not contain dashes"),
279279
),
280280
cfg_options,
@@ -285,8 +285,8 @@ impl ProjectWorkspace {
285285
}
286286
}
287287
for from in sysroot.crates() {
288-
for to in from.deps(&sysroot) {
289-
let name = to.name(&sysroot);
288+
for &to in sysroot[from].deps.iter() {
289+
let name = &sysroot[to].name;
290290
if let (Some(&from), Some(&to)) =
291291
(sysroot_crates.get(&from), sysroot_crates.get(&to))
292292
{
@@ -309,18 +309,18 @@ impl ProjectWorkspace {
309309
// Next, create crates for each package, target pair
310310
for pkg in cargo.packages() {
311311
let mut lib_tgt = None;
312-
for tgt in pkg.targets(&cargo) {
313-
let root = tgt.root(&cargo);
312+
for &tgt in cargo[pkg].targets.iter() {
313+
let root = cargo[tgt].root.as_path();
314314
if let Some(file_id) = load(root) {
315-
let edition = pkg.edition(&cargo);
315+
let edition = cargo[pkg].edition;
316316
let cfg_options = {
317317
let mut opts = default_cfg_options.clone();
318-
opts.insert_features(pkg.features(&cargo).iter().map(Into::into));
318+
opts.insert_features(cargo[pkg].features.iter().map(Into::into));
319319
opts
320320
};
321321
let mut env = Env::default();
322322
let mut extern_source = ExternSource::default();
323-
if let Some(out_dir) = pkg.out_dir(cargo) {
323+
if let Some(out_dir) = &cargo[pkg].out_dir {
324324
// FIXME: We probably mangle non UTF-8 paths here, figure out a better solution
325325
env.set("OUT_DIR", out_dir.to_string_lossy().to_string());
326326
if let Some(&extern_source_id) = extern_source_roots.get(out_dir) {
@@ -330,16 +330,16 @@ impl ProjectWorkspace {
330330
let crate_id = crate_graph.add_crate_root(
331331
file_id,
332332
edition,
333-
Some(CrateName::normalize_dashes(pkg.name(&cargo))),
333+
Some(CrateName::normalize_dashes(&cargo[pkg].name)),
334334
cfg_options,
335335
env,
336336
extern_source,
337337
);
338-
if tgt.kind(&cargo) == TargetKind::Lib {
338+
if cargo[tgt].kind == TargetKind::Lib {
339339
lib_tgt = Some(crate_id);
340340
pkg_to_lib_crate.insert(pkg, crate_id);
341341
}
342-
if tgt.is_proc_macro(&cargo) {
342+
if cargo[tgt].is_proc_macro {
343343
if let Some(proc_macro) = libproc_macro {
344344
if crate_graph
345345
.add_dep(
@@ -351,7 +351,7 @@ impl ProjectWorkspace {
351351
{
352352
log::error!(
353353
"cyclic dependency on proc_macro for {}",
354-
pkg.name(&cargo)
354+
&cargo[pkg].name
355355
)
356356
}
357357
}
@@ -371,15 +371,15 @@ impl ProjectWorkspace {
371371
// For root projects with dashes in their name,
372372
// cargo metadata does not do any normalization,
373373
// so we do it ourselves currently
374-
CrateName::normalize_dashes(pkg.name(&cargo)),
374+
CrateName::normalize_dashes(&cargo[pkg].name),
375375
to,
376376
)
377377
.is_err()
378378
{
379379
{
380380
log::error!(
381381
"cyclic dependency between targets of {}",
382-
pkg.name(&cargo)
382+
&cargo[pkg].name
383383
)
384384
}
385385
}
@@ -391,23 +391,23 @@ impl ProjectWorkspace {
391391
.add_dep(from, CrateName::new("core").unwrap(), core)
392392
.is_err()
393393
{
394-
log::error!("cyclic dependency on core for {}", pkg.name(&cargo))
394+
log::error!("cyclic dependency on core for {}", &cargo[pkg].name)
395395
}
396396
}
397397
if let Some(alloc) = liballoc {
398398
if crate_graph
399399
.add_dep(from, CrateName::new("alloc").unwrap(), alloc)
400400
.is_err()
401401
{
402-
log::error!("cyclic dependency on alloc for {}", pkg.name(&cargo))
402+
log::error!("cyclic dependency on alloc for {}", &cargo[pkg].name)
403403
}
404404
}
405405
if let Some(std) = libstd {
406406
if crate_graph
407407
.add_dep(from, CrateName::new("std").unwrap(), std)
408408
.is_err()
409409
{
410-
log::error!("cyclic dependency on std for {}", pkg.name(&cargo))
410+
log::error!("cyclic dependency on std for {}", &cargo[pkg].name)
411411
}
412412
}
413413
}
@@ -416,7 +416,7 @@ impl ProjectWorkspace {
416416
// Now add a dep edge from all targets of upstream to the lib
417417
// target of downstream.
418418
for pkg in cargo.packages() {
419-
for dep in pkg.dependencies(&cargo) {
419+
for dep in cargo[pkg].dependencies.iter() {
420420
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
421421
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
422422
if crate_graph
@@ -425,8 +425,8 @@ impl ProjectWorkspace {
425425
{
426426
log::error!(
427427
"cyclic dependency {} -> {}",
428-
pkg.name(&cargo),
429-
dep.pkg.name(&cargo)
428+
&cargo[pkg].name,
429+
&cargo[dep.pkg].name
430430
)
431431
}
432432
}

crates/ra_project_model/src/sysroot.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use anyhow::{bail, Context, Result};
44
use std::{
5-
env,
5+
env, ops,
66
path::{Path, PathBuf},
77
process::{Command, Output},
88
};
@@ -19,10 +19,17 @@ pub struct SysrootCrate(RawId);
1919
impl_arena_id!(SysrootCrate);
2020

2121
#[derive(Debug, Clone)]
22-
struct SysrootCrateData {
23-
name: String,
24-
root: PathBuf,
25-
deps: Vec<SysrootCrate>,
22+
pub struct SysrootCrateData {
23+
pub name: String,
24+
pub root: PathBuf,
25+
pub deps: Vec<SysrootCrate>,
26+
}
27+
28+
impl ops::Index<SysrootCrate> for Sysroot {
29+
type Output = SysrootCrateData;
30+
fn index(&self, index: SysrootCrate) -> &SysrootCrateData {
31+
&self.crates[index]
32+
}
2633
}
2734

2835
impl Sysroot {
@@ -129,18 +136,9 @@ fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
129136
Ok(src_path)
130137
}
131138

132-
impl SysrootCrate {
133-
pub fn name(self, sysroot: &Sysroot) -> &str {
134-
&sysroot.crates[self].name
135-
}
136-
pub fn root(self, sysroot: &Sysroot) -> &Path {
137-
sysroot.crates[self].root.as_path()
138-
}
139-
pub fn root_dir(self, sysroot: &Sysroot) -> &Path {
140-
self.root(sysroot).parent().unwrap()
141-
}
142-
pub fn deps<'a>(self, sysroot: &'a Sysroot) -> impl Iterator<Item = SysrootCrate> + 'a {
143-
sysroot.crates[self].deps.iter().copied()
139+
impl SysrootCrateData {
140+
pub fn root_dir(&self) -> &Path {
141+
self.root.parent().unwrap()
144142
}
145143
}
146144

crates/rust-analyzer/src/cargo_target_spec.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ impl CargoTargetSpec {
7777
ProjectWorkspace::Cargo { cargo, .. } => {
7878
let tgt = cargo.target_by_root(&path)?;
7979
Some(CargoTargetSpec {
80-
package: tgt.package(&cargo).name(&cargo).to_string(),
81-
target: tgt.name(&cargo).to_string(),
82-
target_kind: tgt.kind(&cargo),
80+
package: cargo[cargo[tgt].package].name.clone(),
81+
target: cargo[tgt].name.clone(),
82+
target_kind: cargo[tgt].kind,
8383
})
8484
}
8585
ProjectWorkspace::Json { .. } => None,

0 commit comments

Comments
 (0)