Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ae89ca3

Browse files
committed
Auto merge of rust-lang#15161 - lowr:patch/fixture-metadata-library, r=Veykril
internal: add `library` fixture meta Currently, there is no way to specify `CrateOrigin` of a file fixture ([this] might be a bug?). This PR adds `library` meta to explicitly specify the fixture to be `CrateOrigin::Library` and also makes sure crates that belong to a library source root are set `CrateOrigin::Library`. (`library` isn't really the best name. It essentially means that the crate is outside workspace but `non_workspace_member` feels a bit too long. Suggestions for the better name would be appreciated) Additionally: - documents the fixture meta syntax as thoroughly as possible - refactors relevant code [this]: https://github.com/rust-lang/rust-analyzer/blob/4b06d3c595a75fd84bfce2b7f2861a913ed6e530/crates/base-db/src/fixture.rs#L450
2 parents ac4e046 + d51536c commit ae89ca3

File tree

5 files changed

+164
-77
lines changed

5 files changed

+164
-77
lines changed

crates/base-db/src/fixture.rs

Lines changed: 69 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ pub struct ChangeFixture {
102102
pub change: Change,
103103
}
104104

105+
const SOURCE_ROOT_PREFIX: &str = "/";
106+
105107
impl ChangeFixture {
106108
pub fn parse(ra_fixture: &str) -> ChangeFixture {
107109
Self::parse_with_proc_macros(ra_fixture, Vec::new())
@@ -131,7 +133,6 @@ impl ChangeFixture {
131133

132134
let mut file_set = FileSet::default();
133135
let mut current_source_root_kind = SourceRootKind::Local;
134-
let source_root_prefix = "/".to_string();
135136
let mut file_id = FileId(0);
136137
let mut roots = Vec::new();
137138

@@ -151,19 +152,23 @@ impl ChangeFixture {
151152
entry.text.clone()
152153
};
153154

154-
let meta = FileMeta::from(entry);
155-
assert!(meta.path.starts_with(&source_root_prefix));
155+
let meta = FileMeta::from_fixture(entry, current_source_root_kind);
156+
assert!(meta.path.starts_with(SOURCE_ROOT_PREFIX));
156157
if !meta.deps.is_empty() {
157158
assert!(meta.krate.is_some(), "can't specify deps without naming the crate")
158159
}
159160

160-
if let Some(kind) = &meta.introduce_new_source_root {
161-
let root = match current_source_root_kind {
161+
if let Some(kind) = meta.introduce_new_source_root {
162+
assert!(
163+
meta.krate.is_some(),
164+
"new_source_root meta doesn't make sense without crate meta"
165+
);
166+
let prev_kind = mem::replace(&mut current_source_root_kind, kind);
167+
let prev_root = match prev_kind {
162168
SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)),
163169
SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)),
164170
};
165-
roots.push(root);
166-
current_source_root_kind = *kind;
171+
roots.push(prev_root);
167172
}
168173

169174
if let Some((krate, origin, version)) = meta.krate {
@@ -185,7 +190,7 @@ impl ChangeFixture {
185190
Some(toolchain),
186191
);
187192
let prev = crates.insert(crate_name.clone(), crate_id);
188-
assert!(prev.is_none());
193+
assert!(prev.is_none(), "multiple crates with same name: {}", crate_name);
189194
for dep in meta.deps {
190195
let prelude = meta.extern_prelude.contains(&dep);
191196
let dep = CrateName::normalize_dashes(&dep);
@@ -442,51 +447,74 @@ struct FileMeta {
442447
target_data_layout: Option<String>,
443448
}
444449

445-
fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
446-
if let Some((a, b)) = crate_str.split_once('@') {
447-
let (version, origin) = match b.split_once(':') {
448-
Some(("CratesIo", data)) => match data.split_once(',') {
449-
Some((version, url)) => {
450-
(version, CrateOrigin::Local { repo: Some(url.to_owned()), name: None })
451-
}
452-
_ => panic!("Bad crates.io parameter: {data}"),
453-
},
454-
_ => panic!("Bad string for crate origin: {b}"),
455-
};
456-
(a.to_owned(), origin, Some(version.to_string()))
457-
} else {
458-
let crate_origin = match LangCrateOrigin::from(&*crate_str) {
459-
LangCrateOrigin::Other => CrateOrigin::Local { repo: None, name: None },
460-
origin => CrateOrigin::Lang(origin),
461-
};
462-
(crate_str, crate_origin, None)
463-
}
464-
}
465-
466-
impl From<Fixture> for FileMeta {
467-
fn from(f: Fixture) -> FileMeta {
450+
impl FileMeta {
451+
fn from_fixture(f: Fixture, current_source_root_kind: SourceRootKind) -> Self {
468452
let mut cfg = CfgOptions::default();
469-
f.cfg_atoms.iter().for_each(|it| cfg.insert_atom(it.into()));
470-
f.cfg_key_values.iter().for_each(|(k, v)| cfg.insert_key_value(k.into(), v.into()));
453+
for (k, v) in f.cfgs {
454+
if let Some(v) = v {
455+
cfg.insert_key_value(k.into(), v.into());
456+
} else {
457+
cfg.insert_atom(k.into());
458+
}
459+
}
460+
461+
let introduce_new_source_root = f.introduce_new_source_root.map(|kind| match &*kind {
462+
"local" => SourceRootKind::Local,
463+
"library" => SourceRootKind::Library,
464+
invalid => panic!("invalid source root kind '{invalid}'"),
465+
});
466+
let current_source_root_kind =
467+
introduce_new_source_root.unwrap_or(current_source_root_kind);
468+
471469
let deps = f.deps;
472-
FileMeta {
470+
Self {
473471
path: f.path,
474-
krate: f.krate.map(parse_crate),
472+
krate: f.krate.map(|it| parse_crate(it, current_source_root_kind, f.library)),
475473
extern_prelude: f.extern_prelude.unwrap_or_else(|| deps.clone()),
476474
deps,
477475
cfg,
478-
edition: f.edition.as_ref().map_or(Edition::CURRENT, |v| Edition::from_str(v).unwrap()),
476+
edition: f.edition.map_or(Edition::CURRENT, |v| Edition::from_str(&v).unwrap()),
479477
env: f.env.into_iter().collect(),
480-
introduce_new_source_root: f.introduce_new_source_root.map(|kind| match &*kind {
481-
"local" => SourceRootKind::Local,
482-
"library" => SourceRootKind::Library,
483-
invalid => panic!("invalid source root kind '{invalid}'"),
484-
}),
478+
introduce_new_source_root,
485479
target_data_layout: f.target_data_layout,
486480
}
487481
}
488482
}
489483

484+
fn parse_crate(
485+
crate_str: String,
486+
current_source_root_kind: SourceRootKind,
487+
explicit_non_workspace_member: bool,
488+
) -> (String, CrateOrigin, Option<String>) {
489+
// syntax:
490+
// "my_awesome_crate"
491+
// "[email protected],http://example.com"
492+
let (name, repo, version) = if let Some((name, remain)) = crate_str.split_once('@') {
493+
let (version, repo) =
494+
remain.split_once(',').expect("crate meta: found '@' without version and url");
495+
(name.to_owned(), Some(repo.to_owned()), Some(version.to_owned()))
496+
} else {
497+
(crate_str, None, None)
498+
};
499+
500+
let non_workspace_member = explicit_non_workspace_member
501+
|| matches!(current_source_root_kind, SourceRootKind::Library);
502+
503+
let origin = match LangCrateOrigin::from(&*name) {
504+
LangCrateOrigin::Other => {
505+
let name = name.clone();
506+
if non_workspace_member {
507+
CrateOrigin::Library { repo, name }
508+
} else {
509+
CrateOrigin::Local { repo, name: Some(name) }
510+
}
511+
}
512+
origin => CrateOrigin::Lang(origin),
513+
};
514+
515+
(name, origin, version)
516+
}
517+
490518
// Identity mapping
491519
#[derive(Debug)]
492520
struct IdentityProcMacroExpander;

crates/base-db/src/input.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ impl ops::Deref for CrateName {
138138
}
139139
}
140140

141-
/// Origin of the crates. It is used in emitting monikers.
141+
/// Origin of the crates.
142142
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
143143
pub enum CrateOrigin {
144-
/// Crates that are from the rustc workspace
144+
/// Crates that are from the rustc workspace.
145145
Rustc { name: String },
146-
/// Crates that are workspace members,
146+
/// Crates that are workspace members.
147147
Local { repo: Option<String>, name: Option<String> },
148148
/// Crates that are non member libraries.
149149
Library { repo: Option<String>, name: String },

crates/ide/src/moniker.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ use foo::module::func;
320320
fn main() {
321321
func$0();
322322
}
323-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
323+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
324324
pub mod module {
325325
pub fn func() {}
326326
}
@@ -336,7 +336,7 @@ use foo::module::func;
336336
fn main() {
337337
func();
338338
}
339-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
339+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
340340
pub mod module {
341341
pub fn func$0() {}
342342
}
@@ -351,7 +351,7 @@ pub mod module {
351351
fn moniker_for_trait() {
352352
check_moniker(
353353
r#"
354-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
354+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
355355
pub mod module {
356356
pub trait MyTrait {
357357
pub fn func$0() {}
@@ -368,7 +368,7 @@ pub mod module {
368368
fn moniker_for_trait_constant() {
369369
check_moniker(
370370
r#"
371-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
371+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
372372
pub mod module {
373373
pub trait MyTrait {
374374
const MY_CONST$0: u8;
@@ -385,7 +385,7 @@ pub mod module {
385385
fn moniker_for_trait_type() {
386386
check_moniker(
387387
r#"
388-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
388+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
389389
pub mod module {
390390
pub trait MyTrait {
391391
type MyType$0;
@@ -402,7 +402,7 @@ pub mod module {
402402
fn moniker_for_trait_impl_function() {
403403
check_moniker(
404404
r#"
405-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
405+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
406406
pub mod module {
407407
pub trait MyTrait {
408408
pub fn func() {}
@@ -430,7 +430,7 @@ use foo::St;
430430
fn main() {
431431
let x = St { a$0: 2 };
432432
}
433-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
433+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
434434
pub struct St {
435435
pub a: i32,
436436
}
@@ -450,7 +450,7 @@ use foo::module::func;
450450
fn main() {
451451
func();
452452
}
453-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
453+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
454454
pub mod module {
455455
pub fn func() {
456456
let x$0 = 2;

crates/rust-analyzer/src/cli/scip.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ use foo::example_mod::func;
324324
fn main() {
325325
func$0();
326326
}
327-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
327+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
328328
pub mod example_mod {
329329
pub fn func() {}
330330
}
@@ -337,7 +337,7 @@ pub mod example_mod {
337337
fn symbol_for_trait() {
338338
check_symbol(
339339
r#"
340-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
340+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
341341
pub mod module {
342342
pub trait MyTrait {
343343
pub fn func$0() {}
@@ -352,7 +352,7 @@ pub mod module {
352352
fn symbol_for_trait_constant() {
353353
check_symbol(
354354
r#"
355-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
355+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
356356
pub mod module {
357357
pub trait MyTrait {
358358
const MY_CONST$0: u8;
@@ -367,7 +367,7 @@ pub mod module {
367367
fn symbol_for_trait_type() {
368368
check_symbol(
369369
r#"
370-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
370+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
371371
pub mod module {
372372
pub trait MyTrait {
373373
type MyType$0;
@@ -383,7 +383,7 @@ pub mod module {
383383
fn symbol_for_trait_impl_function() {
384384
check_symbol(
385385
r#"
386-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
386+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
387387
pub mod module {
388388
pub trait MyTrait {
389389
pub fn func() {}
@@ -410,7 +410,7 @@ pub mod module {
410410
fn main() {
411411
let x = St { a$0: 2 };
412412
}
413-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
413+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
414414
pub struct St {
415415
pub a: i32,
416416
}
@@ -428,7 +428,7 @@ pub mod module {
428428
fn main() {
429429
func();
430430
}
431-
//- /foo/lib.rs crate:foo@CratesIo:0.1.0,https://a.b/foo.git
431+
//- /foo/lib.rs crate:[email protected],https://a.b/foo.git library
432432
pub mod module {
433433
pub fn func() {
434434
let x$0 = 2;

0 commit comments

Comments
 (0)