mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 04:18:20 +00:00
fix: Make lang items query properly filter out overwritten/excluded sysroots
This commit is contained in:
parent
e10fa9393e
commit
15ac6a21dd
7 changed files with 167 additions and 69 deletions
|
|
@ -3,8 +3,8 @@ use std::{any::TypeId, mem, str::FromStr, sync};
|
|||
|
||||
use base_db::{
|
||||
Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData,
|
||||
DependencyBuilder, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabase, SourceRoot,
|
||||
Version, VfsPath, salsa,
|
||||
DependencyBuilder, Env, FileChange, FileSet, FxIndexMap, LangCrateOrigin, SourceDatabase,
|
||||
SourceRoot, Version, VfsPath, salsa,
|
||||
};
|
||||
use cfg::CfgOptions;
|
||||
use hir_expand::{
|
||||
|
|
@ -20,7 +20,6 @@ use hir_expand::{
|
|||
};
|
||||
use intern::{Symbol, sym};
|
||||
use paths::AbsPathBuf;
|
||||
use rustc_hash::FxHashMap;
|
||||
use span::{Edition, FileId, Span};
|
||||
use stdx::itertools::Itertools;
|
||||
use test_utils::{
|
||||
|
|
@ -147,7 +146,7 @@ impl ChangeFixture {
|
|||
|
||||
let mut files = Vec::new();
|
||||
let mut crate_graph = CrateGraphBuilder::default();
|
||||
let mut crates = FxHashMap::default();
|
||||
let mut crates = FxIndexMap::default();
|
||||
let mut crate_deps = Vec::new();
|
||||
let mut default_crate_root: Option<FileId> = None;
|
||||
let mut default_edition = Edition::CURRENT;
|
||||
|
|
@ -249,37 +248,7 @@ impl ChangeFixture {
|
|||
file_id = FileId::from_raw(file_id.index() + 1);
|
||||
}
|
||||
|
||||
if crates.is_empty() {
|
||||
let crate_root = default_crate_root
|
||||
.expect("missing default crate root, specify a main.rs or lib.rs");
|
||||
crate_graph.add_crate_root(
|
||||
crate_root,
|
||||
default_edition,
|
||||
Some(CrateName::new("ra_test_fixture").unwrap().into()),
|
||||
None,
|
||||
default_cfg.clone(),
|
||||
Some(default_cfg),
|
||||
default_env,
|
||||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
proc_macro_cwd.clone(),
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
} else {
|
||||
for (from, to, prelude) in crate_deps {
|
||||
let from_id = crates[&from];
|
||||
let to_id = crates[&to];
|
||||
let sysroot = crate_graph[to_id].basic.origin.is_lang();
|
||||
crate_graph
|
||||
.add_dep(
|
||||
from_id,
|
||||
DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mini_core) = mini_core {
|
||||
let mini_core = mini_core.map(|mini_core| {
|
||||
let core_file = file_id;
|
||||
file_id = FileId::from_raw(file_id.index() + 1);
|
||||
|
||||
|
|
@ -289,8 +258,6 @@ impl ChangeFixture {
|
|||
|
||||
source_change.change_file(core_file, Some(mini_core.source_code()));
|
||||
|
||||
let all_crates = crate_graph.iter().collect::<Vec<_>>();
|
||||
|
||||
let core_crate = crate_graph.add_crate_root(
|
||||
core_file,
|
||||
Edition::CURRENT,
|
||||
|
|
@ -308,16 +275,58 @@ impl ChangeFixture {
|
|||
crate_ws_data.clone(),
|
||||
);
|
||||
|
||||
for krate in all_crates {
|
||||
(
|
||||
move || {
|
||||
DependencyBuilder::with_prelude(
|
||||
CrateName::new("core").unwrap(),
|
||||
core_crate,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
},
|
||||
core_crate,
|
||||
)
|
||||
});
|
||||
|
||||
if crates.is_empty() {
|
||||
let crate_root = default_crate_root
|
||||
.expect("missing default crate root, specify a main.rs or lib.rs");
|
||||
let root = crate_graph.add_crate_root(
|
||||
crate_root,
|
||||
default_edition,
|
||||
Some(CrateName::new("ra_test_fixture").unwrap().into()),
|
||||
None,
|
||||
default_cfg.clone(),
|
||||
Some(default_cfg),
|
||||
default_env,
|
||||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
proc_macro_cwd.clone(),
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
if let Some((mini_core, _)) = mini_core {
|
||||
crate_graph.add_dep(root, mini_core()).unwrap();
|
||||
}
|
||||
} else {
|
||||
// Insert minicore first to match with `project-model::workspace`
|
||||
if let Some((mini_core, core_crate)) = mini_core {
|
||||
let all_crates = crate_graph.iter().collect::<Vec<_>>();
|
||||
for krate in all_crates {
|
||||
if krate == core_crate {
|
||||
continue;
|
||||
}
|
||||
crate_graph.add_dep(krate, mini_core()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
for (from, to, prelude) in crate_deps {
|
||||
let from_id = crates[&from];
|
||||
let to_id = crates[&to];
|
||||
let sysroot = crate_graph[to_id].basic.origin.is_lang();
|
||||
crate_graph
|
||||
.add_dep(
|
||||
krate,
|
||||
DependencyBuilder::with_prelude(
|
||||
CrateName::new("core").unwrap(),
|
||||
core_crate,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
from_id,
|
||||
DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
@ -627,11 +636,23 @@ impl FileMeta {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ForceNoneLangOrigin {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
fn parse_crate(
|
||||
crate_str: String,
|
||||
current_source_root_kind: SourceRootKind,
|
||||
explicit_non_workspace_member: bool,
|
||||
) -> (String, CrateOrigin, Option<String>) {
|
||||
let (crate_str, force_non_lang_origin) = if let Some(s) = crate_str.strip_prefix("r#") {
|
||||
(s.to_owned(), ForceNoneLangOrigin::Yes)
|
||||
} else {
|
||||
(crate_str, ForceNoneLangOrigin::No)
|
||||
};
|
||||
|
||||
// syntax:
|
||||
// "my_awesome_crate"
|
||||
// "my_awesome_crate@0.0.1,http://example.com"
|
||||
|
|
@ -646,16 +667,25 @@ fn parse_crate(
|
|||
let non_workspace_member = explicit_non_workspace_member
|
||||
|| matches!(current_source_root_kind, SourceRootKind::Library);
|
||||
|
||||
let origin = match LangCrateOrigin::from(&*name) {
|
||||
LangCrateOrigin::Other => {
|
||||
let name = Symbol::intern(&name);
|
||||
if non_workspace_member {
|
||||
CrateOrigin::Library { repo, name }
|
||||
} else {
|
||||
CrateOrigin::Local { repo, name: Some(name) }
|
||||
}
|
||||
let origin = if force_non_lang_origin == ForceNoneLangOrigin::Yes {
|
||||
let name = Symbol::intern(&name);
|
||||
if non_workspace_member {
|
||||
CrateOrigin::Library { repo, name }
|
||||
} else {
|
||||
CrateOrigin::Local { repo, name: Some(name) }
|
||||
}
|
||||
} else {
|
||||
match LangCrateOrigin::from(&*name) {
|
||||
LangCrateOrigin::Other => {
|
||||
let name = Symbol::intern(&name);
|
||||
if non_workspace_member {
|
||||
CrateOrigin::Library { repo, name }
|
||||
} else {
|
||||
CrateOrigin::Local { repo, name: Some(name) }
|
||||
}
|
||||
}
|
||||
origin => CrateOrigin::Lang(origin),
|
||||
}
|
||||
origin => CrateOrigin::Lang(origin),
|
||||
};
|
||||
|
||||
(name, origin, version)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue