mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-04 10:50:15 +00:00
Salsify the crate graph
I.e. make it not one giant input but multiple, for incrementality and decreased memory usage for Salsa 3 reasons.
This commit is contained in:
parent
44f18c3d05
commit
c94e9efbef
108 changed files with 3630 additions and 2512 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2418,6 +2418,7 @@ dependencies = [
|
|||
"span",
|
||||
"stdx",
|
||||
"test-utils",
|
||||
"triomphe",
|
||||
"tt",
|
||||
]
|
||||
|
||||
|
|
|
@ -3,20 +3,18 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use salsa::Durability;
|
||||
use triomphe::Arc;
|
||||
use vfs::FileId;
|
||||
|
||||
use crate::{CrateGraph, CrateId, CrateWorkspaceData, RootQueryDb, SourceRoot, SourceRootId};
|
||||
use crate::{CrateGraphBuilder, CratesIdMap, RootQueryDb, SourceRoot, SourceRootId};
|
||||
|
||||
/// Encapsulate a bunch of raw `.set` calls on the database.
|
||||
#[derive(Default)]
|
||||
pub struct FileChange {
|
||||
pub roots: Option<Vec<SourceRoot>>,
|
||||
pub files_changed: Vec<(FileId, Option<String>)>,
|
||||
pub crate_graph: Option<CrateGraph>,
|
||||
pub ws_data: Option<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>,
|
||||
pub crate_graph: Option<CrateGraphBuilder>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FileChange {
|
||||
|
@ -48,15 +46,11 @@ impl FileChange {
|
|||
self.files_changed.push((file_id, new_text))
|
||||
}
|
||||
|
||||
pub fn set_crate_graph(&mut self, graph: CrateGraph) {
|
||||
pub fn set_crate_graph(&mut self, graph: CrateGraphBuilder) {
|
||||
self.crate_graph = Some(graph);
|
||||
}
|
||||
|
||||
pub fn set_ws_data(&mut self, data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>) {
|
||||
self.ws_data = Some(data);
|
||||
}
|
||||
|
||||
pub fn apply(self, db: &mut dyn RootQueryDb) {
|
||||
pub fn apply(self, db: &mut dyn RootQueryDb) -> Option<CratesIdMap> {
|
||||
let _p = tracing::info_span!("FileChange::apply").entered();
|
||||
if let Some(roots) = self.roots {
|
||||
for (idx, root) in roots.into_iter().enumerate() {
|
||||
|
@ -79,12 +73,11 @@ impl FileChange {
|
|||
let text = text.unwrap_or_default();
|
||||
db.set_file_text_with_durability(file_id, &text, durability)
|
||||
}
|
||||
|
||||
if let Some(crate_graph) = self.crate_graph {
|
||||
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH);
|
||||
}
|
||||
if let Some(data) = self.ws_data {
|
||||
db.set_crate_workspace_data_with_durability(Arc::new(data), Durability::HIGH);
|
||||
return Some(crate_graph.set_in_db(db));
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,23 @@
|
|||
//! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
|
||||
//! actual IO is done and lowered to input.
|
||||
|
||||
use std::hash::BuildHasherDefault;
|
||||
use std::{fmt, mem, ops};
|
||||
|
||||
use cfg::CfgOptions;
|
||||
use cfg::{CfgOptions, HashableCfgOptions};
|
||||
use dashmap::mapref::entry::Entry;
|
||||
use dashmap::DashMap;
|
||||
use intern::Symbol;
|
||||
use la_arena::{Arena, Idx, RawIdx};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
|
||||
use salsa::{Durability, Setter};
|
||||
use span::{Edition, EditionedFileId};
|
||||
use triomphe::Arc;
|
||||
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
|
||||
|
||||
pub type ProcMacroPaths = FxHashMap<CrateId, Result<(String, AbsPathBuf), String>>;
|
||||
use crate::{CrateWorkspaceData, RootQueryDb};
|
||||
|
||||
pub type ProcMacroPaths = FxHashMap<CrateBuilderId, Result<(String, AbsPathBuf), String>>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct SourceRootId(pub u32);
|
||||
|
@ -64,30 +70,31 @@ impl SourceRoot {
|
|||
}
|
||||
}
|
||||
|
||||
/// `CrateGraph` is a bit of information which turns a set of text files into a
|
||||
/// number of Rust crates.
|
||||
///
|
||||
/// Each crate is defined by the `FileId` of its root module, the set of enabled
|
||||
/// `cfg` flags and the set of dependencies.
|
||||
///
|
||||
/// Note that, due to cfg's, there might be several crates for a single `FileId`!
|
||||
///
|
||||
/// For the purposes of analysis, a crate does not have a name. Instead, names
|
||||
/// are specified on dependency edges. That is, a crate might be known under
|
||||
/// different names in different dependent crates.
|
||||
///
|
||||
/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
|
||||
/// language proper, not a concept of the build system. In practice, we get
|
||||
/// `CrateGraph` by lowering `cargo metadata` output.
|
||||
///
|
||||
/// `CrateGraph` is `!Serialize` by design, see
|
||||
/// <https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/architecture.md#serialization>
|
||||
#[derive(Clone, Default)]
|
||||
pub struct CrateGraph {
|
||||
arena: Arena<CrateData>,
|
||||
#[derive(Default, Clone)]
|
||||
pub struct CrateGraphBuilder {
|
||||
arena: Arena<CrateBuilder>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for CrateGraph {
|
||||
pub type CrateBuilderId = Idx<CrateBuilder>;
|
||||
|
||||
impl ops::Index<CrateBuilderId> for CrateGraphBuilder {
|
||||
type Output = CrateBuilder;
|
||||
|
||||
fn index(&self, index: CrateBuilderId) -> &Self::Output {
|
||||
&self.arena[index]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CrateBuilder {
|
||||
pub basic: CrateDataBuilder,
|
||||
pub extra: ExtraCrateData,
|
||||
pub cfg_options: Arc<CfgOptions>,
|
||||
pub env: Env,
|
||||
ws_data: Arc<CrateWorkspaceData>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for CrateGraphBuilder {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_map()
|
||||
.entries(self.arena.iter().map(|(id, data)| (u32::from(id.into_raw()), data)))
|
||||
|
@ -95,8 +102,6 @@ impl fmt::Debug for CrateGraph {
|
|||
}
|
||||
}
|
||||
|
||||
pub type CrateId = Idx<CrateData>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CrateName(Symbol);
|
||||
|
||||
|
@ -272,10 +277,46 @@ impl ReleaseChannel {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CrateData {
|
||||
/// The crate data from which we derive the `Crate`.
|
||||
///
|
||||
/// We want this to contain as little data as possible, because if it contains dependencies and
|
||||
/// something changes, this crate and all of its dependencies ids are invalidated, which causes
|
||||
/// pretty much everything to be recomputed. If the crate id is not invalidated, only this crate's
|
||||
/// information needs to be recomputed.
|
||||
///
|
||||
/// *Most* different crates have different root files (actually, pretty much all of them).
|
||||
/// Still, it is possible to have crates distinguished by other factors (e.g. dependencies).
|
||||
/// So we store only the root file - unless we find that this crate has the same root file as
|
||||
/// another crate, in which case we store all data for one of them (if one is a dependency of
|
||||
/// the other, we store for it, because it has more dependencies to be invalidated).
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UniqueCrateData {
|
||||
root_file_id: FileId,
|
||||
disambiguator: Option<Box<(BuiltCrateData, HashableCfgOptions)>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CrateData<Id> {
|
||||
pub root_file_id: FileId,
|
||||
pub edition: Edition,
|
||||
/// The dependencies of this crate.
|
||||
///
|
||||
/// Note that this may contain more dependencies than the crate actually uses.
|
||||
/// A common example is the test crate which is included but only actually is active when
|
||||
/// declared in source via `extern crate test`.
|
||||
pub dependencies: Vec<Dependency<Id>>,
|
||||
pub origin: CrateOrigin,
|
||||
pub is_proc_macro: bool,
|
||||
/// The working directory to run proc-macros in. This is the workspace root of the cargo workspace
|
||||
/// for workspace members, the crate manifest dir otherwise.
|
||||
pub proc_macro_cwd: Option<AbsPathBuf>,
|
||||
}
|
||||
|
||||
pub type CrateDataBuilder = CrateData<CrateBuilderId>;
|
||||
pub type BuiltCrateData = CrateData<Crate>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ExtraCrateData {
|
||||
pub version: Option<String>,
|
||||
/// A name used in the package's project declaration: for Cargo projects,
|
||||
/// its `[package].name` can be different for other project types or even
|
||||
|
@ -284,21 +325,8 @@ pub struct CrateData {
|
|||
/// For purposes of analysis, crates are anonymous (only names in
|
||||
/// `Dependency` matters), this name should only be used for UI.
|
||||
pub display_name: Option<CrateDisplayName>,
|
||||
pub cfg_options: Arc<CfgOptions>,
|
||||
/// The cfg options that could be used by the crate
|
||||
pub potential_cfg_options: Option<Arc<CfgOptions>>,
|
||||
pub env: Env,
|
||||
/// The dependencies of this crate.
|
||||
///
|
||||
/// Note that this may contain more dependencies than the crate actually uses.
|
||||
/// A common example is the test crate which is included but only actually is active when
|
||||
/// declared in source via `extern crate test`.
|
||||
pub dependencies: Vec<Dependency>,
|
||||
pub origin: CrateOrigin,
|
||||
pub is_proc_macro: bool,
|
||||
/// The working directory to run proc-macros in. This is the workspace root of the cargo workspace
|
||||
/// for workspace members, the crate manifest dir otherwise.
|
||||
pub proc_macro_cwd: Option<AbsPathBuf>,
|
||||
pub potential_cfg_options: Option<CfgOptions>,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq, Eq)]
|
||||
|
@ -326,22 +354,32 @@ impl fmt::Debug for Env {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Dependency {
|
||||
pub crate_id: CrateId,
|
||||
pub struct Dependency<Id> {
|
||||
pub crate_id: Id,
|
||||
pub name: CrateName,
|
||||
prelude: bool,
|
||||
sysroot: bool,
|
||||
}
|
||||
|
||||
impl Dependency {
|
||||
pub fn new(name: CrateName, crate_id: CrateId) -> Self {
|
||||
pub type DependencyBuilder = Dependency<CrateBuilderId>;
|
||||
pub type BuiltDependency = Dependency<Crate>;
|
||||
|
||||
impl DependencyBuilder {
|
||||
pub fn new(name: CrateName, crate_id: CrateBuilderId) -> Self {
|
||||
Self { name, crate_id, prelude: true, sysroot: false }
|
||||
}
|
||||
|
||||
pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool, sysroot: bool) -> Self {
|
||||
pub fn with_prelude(
|
||||
name: CrateName,
|
||||
crate_id: CrateBuilderId,
|
||||
prelude: bool,
|
||||
sysroot: bool,
|
||||
) -> Self {
|
||||
Self { name, crate_id, prelude, sysroot }
|
||||
}
|
||||
}
|
||||
|
||||
impl BuiltDependency {
|
||||
/// Whether this dependency is to be added to the depending crate's extern prelude.
|
||||
pub fn is_prelude(&self) -> bool {
|
||||
self.prelude
|
||||
|
@ -353,7 +391,32 @@ impl Dependency {
|
|||
}
|
||||
}
|
||||
|
||||
impl CrateGraph {
|
||||
pub type CratesIdMap = FxHashMap<CrateBuilderId, Crate>;
|
||||
|
||||
#[salsa::input]
|
||||
pub struct Crate {
|
||||
#[return_ref]
|
||||
pub data: BuiltCrateData,
|
||||
/// Crate data that is not needed for analysis.
|
||||
///
|
||||
/// This is split into a separate field to increase incrementality.
|
||||
#[return_ref]
|
||||
pub extra_data: ExtraCrateData,
|
||||
// This is in `Arc` because it is shared for all crates in a workspace.
|
||||
#[return_ref]
|
||||
pub workspace_data: Arc<CrateWorkspaceData>,
|
||||
// FIXME: Remove this `Arc`.
|
||||
#[return_ref]
|
||||
pub cfg_options: Arc<CfgOptions>,
|
||||
#[return_ref]
|
||||
pub env: Env,
|
||||
}
|
||||
|
||||
/// The mapping from [`UniqueCrateData`] to their [`Crate`] input.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CratesMap(DashMap<UniqueCrateData, Crate, BuildHasherDefault<FxHasher>>);
|
||||
|
||||
impl CrateGraphBuilder {
|
||||
pub fn add_crate_root(
|
||||
&mut self,
|
||||
root_file_id: FileId,
|
||||
|
@ -361,33 +424,34 @@ impl CrateGraph {
|
|||
display_name: Option<CrateDisplayName>,
|
||||
version: Option<String>,
|
||||
cfg_options: Arc<CfgOptions>,
|
||||
potential_cfg_options: Option<Arc<CfgOptions>>,
|
||||
potential_cfg_options: Option<CfgOptions>,
|
||||
mut env: Env,
|
||||
origin: CrateOrigin,
|
||||
is_proc_macro: bool,
|
||||
proc_macro_cwd: Option<AbsPathBuf>,
|
||||
) -> CrateId {
|
||||
ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> CrateBuilderId {
|
||||
env.entries.shrink_to_fit();
|
||||
let data = CrateData {
|
||||
root_file_id,
|
||||
edition,
|
||||
version,
|
||||
display_name,
|
||||
self.arena.alloc(CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id,
|
||||
edition,
|
||||
dependencies: Vec::new(),
|
||||
origin,
|
||||
is_proc_macro,
|
||||
proc_macro_cwd,
|
||||
},
|
||||
extra: ExtraCrateData { version, display_name, potential_cfg_options },
|
||||
cfg_options,
|
||||
potential_cfg_options,
|
||||
env,
|
||||
dependencies: Vec::new(),
|
||||
origin,
|
||||
is_proc_macro,
|
||||
proc_macro_cwd,
|
||||
};
|
||||
self.arena.alloc(data)
|
||||
ws_data,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_dep(
|
||||
&mut self,
|
||||
from: CrateId,
|
||||
dep: Dependency,
|
||||
from: CrateBuilderId,
|
||||
dep: DependencyBuilder,
|
||||
) -> Result<(), CyclicDependenciesError> {
|
||||
let _p = tracing::info_span!("add_dep").entered();
|
||||
|
||||
|
@ -395,37 +459,160 @@ impl CrateGraph {
|
|||
// that out, look for a path in the *opposite* direction, from `to` to
|
||||
// `from`.
|
||||
if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) {
|
||||
let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect();
|
||||
let path =
|
||||
path.into_iter().map(|it| (it, self[it].extra.display_name.clone())).collect();
|
||||
let err = CyclicDependenciesError { path };
|
||||
assert!(err.from().0 == from && err.to().0 == dep.crate_id);
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
self.arena[from].add_dep(dep);
|
||||
self.arena[from].basic.dependencies.push(dep);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.arena.is_empty()
|
||||
pub fn set_in_db(self, db: &mut dyn RootQueryDb) -> CratesIdMap {
|
||||
let mut all_crates = Vec::with_capacity(self.arena.len());
|
||||
let mut visited = FxHashMap::default();
|
||||
let mut visited_root_files = FxHashSet::default();
|
||||
|
||||
let old_all_crates = db.all_crates();
|
||||
|
||||
let crates_map = db.crates_map();
|
||||
// salsa doesn't compare new input to old input to see if they are the same, so here we are doing all the work ourselves.
|
||||
for krate in self.iter() {
|
||||
go(
|
||||
&self,
|
||||
db,
|
||||
&crates_map,
|
||||
&mut visited,
|
||||
&mut visited_root_files,
|
||||
&mut all_crates,
|
||||
krate,
|
||||
);
|
||||
}
|
||||
|
||||
if **old_all_crates != *all_crates {
|
||||
db.set_all_crates_with_durability(
|
||||
Arc::new(all_crates.into_boxed_slice()),
|
||||
Durability::HIGH,
|
||||
);
|
||||
}
|
||||
|
||||
return visited;
|
||||
|
||||
fn go(
|
||||
graph: &CrateGraphBuilder,
|
||||
db: &mut dyn RootQueryDb,
|
||||
crates_map: &CratesMap,
|
||||
visited: &mut FxHashMap<CrateBuilderId, Crate>,
|
||||
visited_root_files: &mut FxHashSet<FileId>,
|
||||
all_crates: &mut Vec<Crate>,
|
||||
source: CrateBuilderId,
|
||||
) -> Crate {
|
||||
if let Some(&crate_id) = visited.get(&source) {
|
||||
return crate_id;
|
||||
}
|
||||
let krate = &graph[source];
|
||||
let dependencies = krate
|
||||
.basic
|
||||
.dependencies
|
||||
.iter()
|
||||
.map(|dep| BuiltDependency {
|
||||
crate_id: go(
|
||||
graph,
|
||||
db,
|
||||
crates_map,
|
||||
visited,
|
||||
visited_root_files,
|
||||
all_crates,
|
||||
dep.crate_id,
|
||||
),
|
||||
name: dep.name.clone(),
|
||||
prelude: dep.prelude,
|
||||
sysroot: dep.sysroot,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let crate_data = BuiltCrateData {
|
||||
dependencies,
|
||||
edition: krate.basic.edition,
|
||||
is_proc_macro: krate.basic.is_proc_macro,
|
||||
origin: krate.basic.origin.clone(),
|
||||
root_file_id: krate.basic.root_file_id,
|
||||
proc_macro_cwd: krate.basic.proc_macro_cwd.clone(),
|
||||
};
|
||||
let disambiguator = if visited_root_files.insert(krate.basic.root_file_id) {
|
||||
None
|
||||
} else {
|
||||
Some(Box::new((crate_data.clone(), krate.cfg_options.to_hashable())))
|
||||
};
|
||||
|
||||
let unique_crate_data =
|
||||
UniqueCrateData { root_file_id: krate.basic.root_file_id, disambiguator };
|
||||
let crate_input = match crates_map.0.entry(unique_crate_data) {
|
||||
Entry::Occupied(entry) => {
|
||||
let old_crate = *entry.get();
|
||||
if crate_data != *old_crate.data(db) {
|
||||
old_crate.set_data(db).with_durability(Durability::HIGH).to(crate_data);
|
||||
}
|
||||
if krate.extra != *old_crate.extra_data(db) {
|
||||
old_crate
|
||||
.set_extra_data(db)
|
||||
.with_durability(Durability::HIGH)
|
||||
.to(krate.extra.clone());
|
||||
}
|
||||
if krate.cfg_options != *old_crate.cfg_options(db) {
|
||||
old_crate
|
||||
.set_cfg_options(db)
|
||||
.with_durability(Durability::HIGH)
|
||||
.to(krate.cfg_options.clone());
|
||||
}
|
||||
if krate.env != *old_crate.env(db) {
|
||||
old_crate
|
||||
.set_env(db)
|
||||
.with_durability(Durability::HIGH)
|
||||
.to(krate.env.clone());
|
||||
}
|
||||
if krate.ws_data != *old_crate.workspace_data(db) {
|
||||
old_crate
|
||||
.set_workspace_data(db)
|
||||
.with_durability(Durability::HIGH)
|
||||
.to(krate.ws_data.clone());
|
||||
}
|
||||
old_crate
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
let input = Crate::builder(
|
||||
crate_data,
|
||||
krate.extra.clone(),
|
||||
krate.ws_data.clone(),
|
||||
krate.cfg_options.clone(),
|
||||
krate.env.clone(),
|
||||
)
|
||||
.durability(Durability::HIGH)
|
||||
.new(db);
|
||||
entry.insert(input);
|
||||
input
|
||||
}
|
||||
};
|
||||
all_crates.push(crate_input);
|
||||
visited.insert(source, crate_input);
|
||||
crate_input
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.arena.len()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = CrateId> + '_ {
|
||||
pub fn iter(&self) -> impl Iterator<Item = CrateBuilderId> + '_ {
|
||||
self.arena.iter().map(|(idx, _)| idx)
|
||||
}
|
||||
|
||||
// FIXME: used for fixing up the toolchain sysroot, should be removed and done differently
|
||||
#[doc(hidden)]
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (CrateId, &mut CrateData)> + '_ {
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (CrateBuilderId, &mut CrateBuilder)> + '_ {
|
||||
self.arena.iter_mut()
|
||||
}
|
||||
|
||||
/// Returns an iterator over all transitive dependencies of the given crate,
|
||||
/// including the crate itself.
|
||||
pub fn transitive_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
|
||||
pub fn transitive_deps(&self, of: CrateBuilderId) -> impl Iterator<Item = CrateBuilderId> {
|
||||
let mut worklist = vec![of];
|
||||
let mut deps = FxHashSet::default();
|
||||
|
||||
|
@ -434,42 +621,15 @@ impl CrateGraph {
|
|||
continue;
|
||||
}
|
||||
|
||||
worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id));
|
||||
worklist.extend(self[krate].basic.dependencies.iter().map(|dep| dep.crate_id));
|
||||
}
|
||||
|
||||
deps.into_iter()
|
||||
}
|
||||
|
||||
/// Returns all transitive reverse dependencies of the given crate,
|
||||
/// including the crate itself.
|
||||
pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator<Item = CrateId> {
|
||||
let mut worklist = vec![of];
|
||||
let mut rev_deps = FxHashSet::default();
|
||||
rev_deps.insert(of);
|
||||
|
||||
let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
|
||||
self.arena.iter().for_each(|(krate, data)| {
|
||||
data.dependencies
|
||||
.iter()
|
||||
.for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate))
|
||||
});
|
||||
|
||||
while let Some(krate) = worklist.pop() {
|
||||
if let Some(krate_rev_deps) = inverted_graph.get(&krate) {
|
||||
krate_rev_deps
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&rev_dep| rev_deps.insert(rev_dep))
|
||||
.for_each(|rev_dep| worklist.push(rev_dep));
|
||||
}
|
||||
}
|
||||
|
||||
rev_deps.into_iter()
|
||||
}
|
||||
|
||||
/// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate
|
||||
/// come before the crate itself).
|
||||
pub fn crates_in_topological_order(&self) -> Vec<CrateId> {
|
||||
fn crates_in_topological_order(&self) -> Vec<CrateBuilderId> {
|
||||
let mut res = Vec::new();
|
||||
let mut visited = FxHashSet::default();
|
||||
|
||||
|
@ -480,15 +640,15 @@ impl CrateGraph {
|
|||
return res;
|
||||
|
||||
fn go(
|
||||
graph: &CrateGraph,
|
||||
visited: &mut FxHashSet<CrateId>,
|
||||
res: &mut Vec<CrateId>,
|
||||
source: CrateId,
|
||||
graph: &CrateGraphBuilder,
|
||||
visited: &mut FxHashSet<CrateBuilderId>,
|
||||
res: &mut Vec<CrateBuilderId>,
|
||||
source: CrateBuilderId,
|
||||
) {
|
||||
if !visited.insert(source) {
|
||||
return;
|
||||
}
|
||||
for dep in graph[source].dependencies.iter() {
|
||||
for dep in graph[source].basic.dependencies.iter() {
|
||||
go(graph, visited, res, dep.crate_id)
|
||||
}
|
||||
res.push(source)
|
||||
|
@ -504,23 +664,27 @@ impl CrateGraph {
|
|||
/// Returns a map mapping `other`'s IDs to the new IDs in `self`.
|
||||
pub fn extend(
|
||||
&mut self,
|
||||
mut other: CrateGraph,
|
||||
mut other: CrateGraphBuilder,
|
||||
proc_macros: &mut ProcMacroPaths,
|
||||
) -> FxHashMap<CrateId, CrateId> {
|
||||
) -> FxHashMap<CrateBuilderId, CrateBuilderId> {
|
||||
// Sorting here is a bit pointless because the input is likely already sorted.
|
||||
// However, the overhead is small and it makes the `extend` method harder to misuse.
|
||||
self.arena
|
||||
.iter_mut()
|
||||
.for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id));
|
||||
.for_each(|(_, data)| data.basic.dependencies.sort_by_key(|dep| dep.crate_id));
|
||||
|
||||
let m = self.len();
|
||||
let m = self.arena.len();
|
||||
let topo = other.crates_in_topological_order();
|
||||
let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default();
|
||||
let mut id_map: FxHashMap<CrateBuilderId, CrateBuilderId> = FxHashMap::default();
|
||||
for topo in topo {
|
||||
let crate_data = &mut other.arena[topo];
|
||||
|
||||
crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
|
||||
crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
|
||||
crate_data
|
||||
.basic
|
||||
.dependencies
|
||||
.iter_mut()
|
||||
.for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
|
||||
crate_data.basic.dependencies.sort_by_key(|dep| dep.crate_id);
|
||||
|
||||
let find = self.arena.iter().take(m).find_map(|(k, v)| (v == crate_data).then_some(k));
|
||||
let new_id = find.unwrap_or_else(|| self.arena.alloc(crate_data.clone()));
|
||||
|
@ -534,10 +698,10 @@ impl CrateGraph {
|
|||
|
||||
fn find_path(
|
||||
&self,
|
||||
visited: &mut FxHashSet<CrateId>,
|
||||
from: CrateId,
|
||||
to: CrateId,
|
||||
) -> Option<Vec<CrateId>> {
|
||||
visited: &mut FxHashSet<CrateBuilderId>,
|
||||
from: CrateBuilderId,
|
||||
to: CrateBuilderId,
|
||||
) -> Option<Vec<CrateBuilderId>> {
|
||||
if !visited.insert(from) {
|
||||
return None;
|
||||
}
|
||||
|
@ -546,7 +710,7 @@ impl CrateGraph {
|
|||
return Some(vec![to]);
|
||||
}
|
||||
|
||||
for dep in &self[from].dependencies {
|
||||
for dep in &self[from].basic.dependencies {
|
||||
let crate_id = dep.crate_id;
|
||||
if let Some(mut path) = self.find_path(visited, crate_id, to) {
|
||||
path.push(from);
|
||||
|
@ -559,7 +723,10 @@ impl CrateGraph {
|
|||
|
||||
/// Removes all crates from this crate graph except for the ones in `to_keep` and fixes up the dependencies.
|
||||
/// Returns a mapping from old crate ids to new crate ids.
|
||||
pub fn remove_crates_except(&mut self, to_keep: &[CrateId]) -> Vec<Option<CrateId>> {
|
||||
pub fn remove_crates_except(
|
||||
&mut self,
|
||||
to_keep: &[CrateBuilderId],
|
||||
) -> Vec<Option<CrateBuilderId>> {
|
||||
let mut id_map = vec![None; self.arena.len()];
|
||||
self.arena = std::mem::take(&mut self.arena)
|
||||
.into_iter()
|
||||
|
@ -567,12 +734,12 @@ impl CrateGraph {
|
|||
.enumerate()
|
||||
.map(|(new_id, (id, data))| {
|
||||
id_map[id.into_raw().into_u32() as usize] =
|
||||
Some(CrateId::from_raw(RawIdx::from_u32(new_id as u32)));
|
||||
Some(CrateBuilderId::from_raw(RawIdx::from_u32(new_id as u32)));
|
||||
data
|
||||
})
|
||||
.collect();
|
||||
for (_, data) in self.arena.iter_mut() {
|
||||
data.dependencies.iter_mut().for_each(|dep| {
|
||||
data.basic.dependencies.iter_mut().for_each(|dep| {
|
||||
dep.crate_id =
|
||||
id_map[dep.crate_id.into_raw().into_u32() as usize].expect("crate was filtered")
|
||||
});
|
||||
|
@ -585,20 +752,34 @@ impl CrateGraph {
|
|||
}
|
||||
}
|
||||
|
||||
impl ops::Index<CrateId> for CrateGraph {
|
||||
type Output = CrateData;
|
||||
fn index(&self, crate_id: CrateId) -> &CrateData {
|
||||
&self.arena[crate_id]
|
||||
pub(crate) fn transitive_rev_deps(db: &dyn RootQueryDb, of: Crate) -> FxHashSet<Crate> {
|
||||
let mut worklist = vec![of];
|
||||
let mut rev_deps = FxHashSet::default();
|
||||
rev_deps.insert(of);
|
||||
|
||||
let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
|
||||
db.all_crates().iter().for_each(|&krate| {
|
||||
krate
|
||||
.data(db)
|
||||
.dependencies
|
||||
.iter()
|
||||
.for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate))
|
||||
});
|
||||
|
||||
while let Some(krate) = worklist.pop() {
|
||||
if let Some(crate_rev_deps) = inverted_graph.get(&krate) {
|
||||
crate_rev_deps
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&rev_dep| rev_deps.insert(rev_dep))
|
||||
.for_each(|rev_dep| worklist.push(rev_dep));
|
||||
}
|
||||
}
|
||||
|
||||
rev_deps
|
||||
}
|
||||
|
||||
impl CrateData {
|
||||
/// Add a dependency to `self` without checking if the dependency
|
||||
// is existent among `self.dependencies`.
|
||||
fn add_dep(&mut self, dep: Dependency) {
|
||||
self.dependencies.push(dep)
|
||||
}
|
||||
|
||||
impl BuiltCrateData {
|
||||
pub fn root_file_id(&self) -> EditionedFileId {
|
||||
EditionedFileId::new(self.root_file_id, self.edition)
|
||||
}
|
||||
|
@ -657,21 +838,21 @@ impl<'a> IntoIterator for &'a Env {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct CyclicDependenciesError {
|
||||
path: Vec<(CrateId, Option<CrateDisplayName>)>,
|
||||
path: Vec<(CrateBuilderId, Option<CrateDisplayName>)>,
|
||||
}
|
||||
|
||||
impl CyclicDependenciesError {
|
||||
fn from(&self) -> &(CrateId, Option<CrateDisplayName>) {
|
||||
fn from(&self) -> &(CrateBuilderId, Option<CrateDisplayName>) {
|
||||
self.path.first().unwrap()
|
||||
}
|
||||
fn to(&self) -> &(CrateId, Option<CrateDisplayName>) {
|
||||
fn to(&self) -> &(CrateBuilderId, Option<CrateDisplayName>) {
|
||||
self.path.last().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CyclicDependenciesError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let render = |(id, name): &(CrateId, Option<CrateDisplayName>)| match name {
|
||||
let render = |(id, name): &(CrateBuilderId, Option<CrateDisplayName>)| match name {
|
||||
Some(it) => format!("{it}({id:?})"),
|
||||
None => format!("{id:?}"),
|
||||
};
|
||||
|
@ -688,13 +869,19 @@ impl fmt::Display for CyclicDependenciesError {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::CrateOrigin;
|
||||
use triomphe::Arc;
|
||||
|
||||
use super::{CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId};
|
||||
use crate::{CrateWorkspaceData, DependencyBuilder};
|
||||
|
||||
use super::{CrateGraphBuilder, CrateName, CrateOrigin, Edition::Edition2018, Env, FileId};
|
||||
|
||||
fn empty_ws_data() -> Arc<CrateWorkspaceData> {
|
||||
Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None })
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_cyclic_dependency_indirect() {
|
||||
let mut graph = CrateGraph::default();
|
||||
let mut graph = CrateGraphBuilder::default();
|
||||
let crate1 = graph.add_crate_root(
|
||||
FileId::from_raw(1u32),
|
||||
Edition2018,
|
||||
|
@ -706,6 +893,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate2 = graph.add_crate_root(
|
||||
FileId::from_raw(2u32),
|
||||
|
@ -718,6 +906,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate3 = graph.add_crate_root(
|
||||
FileId::from_raw(3u32),
|
||||
|
@ -730,21 +919,22 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
assert!(graph
|
||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.is_ok());
|
||||
assert!(graph
|
||||
.add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,))
|
||||
.add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,))
|
||||
.is_ok());
|
||||
assert!(graph
|
||||
.add_dep(crate3, Dependency::new(CrateName::new("crate1").unwrap(), crate1,))
|
||||
.add_dep(crate3, DependencyBuilder::new(CrateName::new("crate1").unwrap(), crate1,))
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_cyclic_dependency_direct() {
|
||||
let mut graph = CrateGraph::default();
|
||||
let mut graph = CrateGraphBuilder::default();
|
||||
let crate1 = graph.add_crate_root(
|
||||
FileId::from_raw(1u32),
|
||||
Edition2018,
|
||||
|
@ -756,6 +946,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate2 = graph.add_crate_root(
|
||||
FileId::from_raw(2u32),
|
||||
|
@ -768,18 +959,19 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
assert!(graph
|
||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.is_ok());
|
||||
assert!(graph
|
||||
.add_dep(crate2, Dependency::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.add_dep(crate2, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let mut graph = CrateGraph::default();
|
||||
let mut graph = CrateGraphBuilder::default();
|
||||
let crate1 = graph.add_crate_root(
|
||||
FileId::from_raw(1u32),
|
||||
Edition2018,
|
||||
|
@ -791,6 +983,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate2 = graph.add_crate_root(
|
||||
FileId::from_raw(2u32),
|
||||
|
@ -803,6 +996,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate3 = graph.add_crate_root(
|
||||
FileId::from_raw(3u32),
|
||||
|
@ -815,18 +1009,19 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
assert!(graph
|
||||
.add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,))
|
||||
.is_ok());
|
||||
assert!(graph
|
||||
.add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,))
|
||||
.add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,))
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dashes_are_normalized() {
|
||||
let mut graph = CrateGraph::default();
|
||||
let mut graph = CrateGraphBuilder::default();
|
||||
let crate1 = graph.add_crate_root(
|
||||
FileId::from_raw(1u32),
|
||||
Edition2018,
|
||||
|
@ -838,6 +1033,7 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
let crate2 = graph.add_crate_root(
|
||||
FileId::from_raw(2u32),
|
||||
|
@ -850,16 +1046,22 @@ mod tests {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
empty_ws_data(),
|
||||
);
|
||||
assert!(graph
|
||||
.add_dep(
|
||||
crate1,
|
||||
Dependency::new(CrateName::normalize_dashes("crate-name-with-dashes"), crate2,)
|
||||
DependencyBuilder::new(
|
||||
CrateName::normalize_dashes("crate-name-with-dashes"),
|
||||
crate2,
|
||||
)
|
||||
)
|
||||
.is_ok());
|
||||
assert_eq!(
|
||||
graph[crate1].dependencies,
|
||||
vec![Dependency::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,)]
|
||||
graph.arena[crate1].basic.dependencies,
|
||||
vec![
|
||||
DependencyBuilder::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,15 @@ use std::hash::BuildHasherDefault;
|
|||
pub use crate::{
|
||||
change::FileChange,
|
||||
input::{
|
||||
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env,
|
||||
LangCrateOrigin, ProcMacroPaths, ReleaseChannel, SourceRoot, SourceRootId,
|
||||
TargetLayoutLoadResult,
|
||||
BuiltCrateData, BuiltDependency, Crate, CrateBuilder, CrateBuilderId, CrateDataBuilder,
|
||||
CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CratesIdMap, CratesMap,
|
||||
DependencyBuilder, Env, ExtraCrateData, LangCrateOrigin, ProcMacroPaths, ReleaseChannel,
|
||||
SourceRoot, SourceRootId, TargetLayoutLoadResult, UniqueCrateData,
|
||||
},
|
||||
};
|
||||
use dashmap::{mapref::entry::Entry, DashMap};
|
||||
pub use query_group::{self};
|
||||
use rustc_hash::{FxHashMap, FxHasher};
|
||||
use rustc_hash::{FxHashSet, FxHasher};
|
||||
pub use salsa::{self};
|
||||
use salsa::{Durability, Setter};
|
||||
pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
|
||||
|
@ -200,21 +201,53 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
|
|||
/// Returns the set of errors obtained from parsing the file including validation errors.
|
||||
fn parse_errors(&self, file_id: EditionedFileId) -> Option<Arc<[SyntaxError]>>;
|
||||
|
||||
/// The crate graph.
|
||||
#[salsa::input]
|
||||
fn crate_graph(&self) -> Arc<CrateGraph>;
|
||||
|
||||
#[salsa::input]
|
||||
fn crate_workspace_data(&self) -> Arc<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>;
|
||||
|
||||
#[salsa::transparent]
|
||||
fn toolchain_channel(&self, krate: CrateId) -> Option<ReleaseChannel>;
|
||||
fn toolchain_channel(&self, krate: Crate) -> Option<ReleaseChannel>;
|
||||
|
||||
/// Crates whose root file is in `id`.
|
||||
fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>;
|
||||
fn source_root_crates(&self, id: SourceRootId) -> Arc<[Crate]>;
|
||||
|
||||
#[salsa::transparent]
|
||||
fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>;
|
||||
fn relevant_crates(&self, file_id: FileId) -> Arc<[Crate]>;
|
||||
|
||||
/// Returns the crates in topological order.
|
||||
///
|
||||
/// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications.
|
||||
#[salsa::input]
|
||||
fn all_crates(&self) -> Arc<Box<[Crate]>>;
|
||||
|
||||
/// Returns an iterator over all transitive dependencies of the given crate,
|
||||
/// including the crate itself.
|
||||
///
|
||||
/// **Warning**: do not use this query in analysis! It kills incrementality across crate metadata modifications.
|
||||
///
|
||||
#[salsa::transparent]
|
||||
fn transitive_deps(&self, crate_id: Crate) -> FxHashSet<Crate>;
|
||||
|
||||
/// Returns all transitive reverse dependencies of the given crate,
|
||||
/// including the crate itself.
|
||||
///
|
||||
/// **Warning**: Do not use this query in analysis! It kills incrementality across crate metadata modifications.
|
||||
#[salsa::invoke(input::transitive_rev_deps)]
|
||||
#[salsa::transparent]
|
||||
fn transitive_rev_deps(&self, of: Crate) -> FxHashSet<Crate>;
|
||||
}
|
||||
|
||||
pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Crate> {
|
||||
// There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
|
||||
// and removing that is a bit difficult.
|
||||
let mut worklist = vec![crate_id];
|
||||
let mut deps = FxHashSet::default();
|
||||
|
||||
while let Some(krate) = worklist.pop() {
|
||||
if !deps.insert(krate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
|
||||
}
|
||||
|
||||
deps
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
|
@ -257,6 +290,9 @@ pub trait SourceDatabase: salsa::Database {
|
|||
let source_root = self.source_root(source_root.source_root_id(self));
|
||||
source_root.source_root(self).resolve_path(path)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
fn crates_map(&self) -> Arc<CratesMap>;
|
||||
}
|
||||
|
||||
/// Crate related data shared by the whole workspace.
|
||||
|
@ -268,12 +304,8 @@ pub struct CrateWorkspaceData {
|
|||
pub toolchain: Option<Version>,
|
||||
}
|
||||
|
||||
fn toolchain_channel(db: &dyn RootQueryDb, krate: CrateId) -> Option<ReleaseChannel> {
|
||||
db.crate_workspace_data()
|
||||
.get(&krate)?
|
||||
.toolchain
|
||||
.as_ref()
|
||||
.and_then(|v| ReleaseChannel::from_str(&v.pre))
|
||||
fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option<ReleaseChannel> {
|
||||
krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
|
||||
}
|
||||
|
||||
fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFile> {
|
||||
|
@ -291,21 +323,19 @@ fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<Arc<[S
|
|||
}
|
||||
}
|
||||
|
||||
fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[CrateId]> {
|
||||
let graph = db.crate_graph();
|
||||
let mut crates = graph
|
||||
fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[Crate]> {
|
||||
let crates = db.all_crates();
|
||||
crates
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|&krate| {
|
||||
let root_file = graph[krate].root_file_id;
|
||||
let root_file = krate.data(db).root_file_id;
|
||||
db.file_source_root(root_file).source_root_id(db) == id
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
crates.sort();
|
||||
crates.dedup();
|
||||
crates.into_iter().collect()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[CrateId]> {
|
||||
fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> {
|
||||
let _p = tracing::info_span!("relevant_crates").entered();
|
||||
|
||||
let source_root = db.file_source_root(file_id);
|
||||
|
|
|
@ -104,6 +104,12 @@ impl CfgOptions {
|
|||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_hashable(&self) -> HashableCfgOptions {
|
||||
let mut enabled = self.enabled.iter().cloned().collect::<Box<[_]>>();
|
||||
enabled.sort_unstable();
|
||||
HashableCfgOptions { _enabled: enabled }
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<CfgAtom> for CfgOptions {
|
||||
|
@ -256,3 +262,9 @@ impl fmt::Display for InactiveReason {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A `CfgOptions` that implements `Hash`, for the sake of hashing only.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct HashableCfgOptions {
|
||||
_enabled: Box<[CfgAtom]>,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{borrow::Cow, hash::Hash, ops};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use cfg::{CfgExpr, CfgOptions};
|
||||
use either::Either;
|
||||
use hir_expand::{
|
||||
|
@ -44,7 +44,7 @@ impl Attrs {
|
|||
(**self).iter().find(|attr| attr.id == id)
|
||||
}
|
||||
|
||||
pub(crate) fn filter(db: &dyn DefDatabase, krate: CrateId, raw_attrs: RawAttrs) -> Attrs {
|
||||
pub(crate) fn filter(db: &dyn DefDatabase, krate: Crate, raw_attrs: RawAttrs) -> Attrs {
|
||||
Attrs(raw_attrs.filter(db.upcast(), krate))
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ impl Attrs {
|
|||
// FIXME: There should be some proper form of mapping between item tree field ids and hir field ids
|
||||
let mut res = ArenaMap::default();
|
||||
|
||||
let crate_graph = db.crate_graph();
|
||||
let item_tree;
|
||||
let (parent, fields, krate) = match v {
|
||||
VariantId::EnumVariantId(it) => {
|
||||
|
@ -102,7 +101,7 @@ impl Attrs {
|
|||
}
|
||||
};
|
||||
|
||||
let cfg_options = &crate_graph[krate].cfg_options;
|
||||
let cfg_options = krate.cfg_options(db);
|
||||
|
||||
let mut idx = 0;
|
||||
for (id, _field) in fields.iter().enumerate() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
pub mod adt;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_expand::{
|
||||
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||
attr_resolution::ResolvedAttr,
|
||||
diagnostics::{DefDiagnostic, DefDiagnostics},
|
||||
proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind},
|
||||
DefMap, MacroSubNs,
|
||||
DefMap, LocalDefMap, MacroSubNs,
|
||||
},
|
||||
path::ImportAlias,
|
||||
type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap},
|
||||
|
@ -57,8 +57,7 @@ impl FunctionData {
|
|||
item_tree[func.visibility].clone()
|
||||
};
|
||||
|
||||
let crate_graph = db.crate_graph();
|
||||
let cfg_options = &crate_graph[krate].cfg_options;
|
||||
let cfg_options = krate.cfg_options(db);
|
||||
let attr_owner = |idx| {
|
||||
item_tree::AttrOwner::Param(loc.id.value, Idx::from_raw(RawIdx::from(idx as u32)))
|
||||
};
|
||||
|
@ -525,7 +524,7 @@ pub struct ExternCrateDeclData {
|
|||
pub name: Name,
|
||||
pub alias: Option<ImportAlias>,
|
||||
pub visibility: RawVisibility,
|
||||
pub crate_id: Option<CrateId>,
|
||||
pub crate_id: Option<Crate>,
|
||||
}
|
||||
|
||||
impl ExternCrateDeclData {
|
||||
|
@ -542,7 +541,7 @@ impl ExternCrateDeclData {
|
|||
let crate_id = if name == sym::self_.clone() {
|
||||
Some(krate)
|
||||
} else {
|
||||
db.crate_graph()[krate].dependencies.iter().find_map(|dep| {
|
||||
krate.data(db).dependencies.iter().find_map(|dep| {
|
||||
if dep.name.symbol() == name.symbol() {
|
||||
Some(dep.crate_id)
|
||||
} else {
|
||||
|
@ -633,6 +632,7 @@ struct AssocItemCollector<'a> {
|
|||
db: &'a dyn DefDatabase,
|
||||
module_id: ModuleId,
|
||||
def_map: Arc<DefMap>,
|
||||
local_def_map: Arc<LocalDefMap>,
|
||||
diagnostics: Vec<DefDiagnostic>,
|
||||
container: ItemContainerId,
|
||||
expander: Expander,
|
||||
|
@ -648,10 +648,12 @@ impl<'a> AssocItemCollector<'a> {
|
|||
file_id: HirFileId,
|
||||
container: ItemContainerId,
|
||||
) -> Self {
|
||||
let (def_map, local_def_map) = module_id.local_def_map(db);
|
||||
Self {
|
||||
db,
|
||||
module_id,
|
||||
def_map: module_id.def_map(db),
|
||||
def_map,
|
||||
local_def_map,
|
||||
container,
|
||||
expander: Expander::new(db, file_id, module_id),
|
||||
items: Vec::new(),
|
||||
|
@ -697,6 +699,7 @@ impl<'a> AssocItemCollector<'a> {
|
|||
let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id };
|
||||
|
||||
match self.def_map.resolve_attr_macro(
|
||||
&self.local_def_map,
|
||||
self.db,
|
||||
self.module_id.local_id,
|
||||
ast_id_with_path,
|
||||
|
@ -780,6 +783,7 @@ impl<'a> AssocItemCollector<'a> {
|
|||
let resolver = |path: &_| {
|
||||
self.def_map
|
||||
.resolve_path(
|
||||
&self.local_def_map,
|
||||
self.db,
|
||||
module,
|
||||
path,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Defines hir-level representation of structs, enums and unions
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use bitflags::bitflags;
|
||||
use cfg::CfgOptions;
|
||||
use either::Either;
|
||||
|
@ -90,7 +90,7 @@ pub struct FieldData {
|
|||
|
||||
fn repr_from_value(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
item_tree: &ItemTree,
|
||||
of: AttrOwner,
|
||||
) -> Option<ReprOptions> {
|
||||
|
@ -222,7 +222,7 @@ impl StructData {
|
|||
loc.container.local_id,
|
||||
loc.id.tree_id(),
|
||||
&item_tree,
|
||||
&db.crate_graph()[krate].cfg_options,
|
||||
krate.cfg_options(db),
|
||||
FieldParent::Struct(loc.id.value),
|
||||
&strukt.fields,
|
||||
None,
|
||||
|
@ -274,7 +274,7 @@ impl StructData {
|
|||
loc.container.local_id,
|
||||
loc.id.tree_id(),
|
||||
&item_tree,
|
||||
&db.crate_graph()[krate].cfg_options,
|
||||
krate.cfg_options(db),
|
||||
FieldParent::Union(loc.id.value),
|
||||
&union.fields,
|
||||
None,
|
||||
|
@ -377,7 +377,7 @@ impl EnumVariantData {
|
|||
container.local_id,
|
||||
loc.id.tree_id(),
|
||||
&item_tree,
|
||||
&db.crate_graph()[krate].cfg_options,
|
||||
krate.cfg_options(db),
|
||||
FieldParent::Variant(loc.id.value),
|
||||
&variant.fields,
|
||||
Some(item_tree[loc.parent.lookup(db).id.value].visibility),
|
||||
|
@ -448,7 +448,7 @@ pub enum StructKind {
|
|||
|
||||
fn lower_fields(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
container: LocalModuleId,
|
||||
tree_id: TreeId,
|
||||
item_tree: &ItemTree,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! Defines database & queries for name resolution.
|
||||
use base_db::{CrateId, RootQueryDb, SourceDatabase, Upcast};
|
||||
use base_db::{Crate, RootQueryDb, SourceDatabase, Upcast};
|
||||
use either::Either;
|
||||
use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId};
|
||||
use intern::sym;
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||
import_map::ImportMap,
|
||||
item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps},
|
||||
lang_item::{self, LangItem, LangItemTarget, LangItems},
|
||||
nameres::{diagnostics::DefDiagnostics, DefMap},
|
||||
nameres::{diagnostics::DefDiagnostics, DefMap, LocalDefMap},
|
||||
tt,
|
||||
type_ref::TypesSourceMap,
|
||||
visibility::{self, Visibility},
|
||||
|
@ -130,8 +130,11 @@ pub trait DefDatabase:
|
|||
block_id: BlockId,
|
||||
) -> (Arc<ItemTree>, Arc<ItemTreeSourceMaps>);
|
||||
|
||||
#[salsa::invoke(DefMap::crate_def_map_query)]
|
||||
fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
|
||||
#[salsa::invoke_actual(DefMap::crate_local_def_map_query)]
|
||||
fn crate_local_def_map(&self, krate: Crate) -> (Arc<DefMap>, Arc<LocalDefMap>);
|
||||
|
||||
#[salsa::invoke_actual(DefMap::crate_def_map_query)]
|
||||
fn crate_def_map(&self, krate: Crate) -> Arc<DefMap>;
|
||||
|
||||
/// Computes the block-level `DefMap`.
|
||||
#[salsa::invoke_actual(DefMap::block_def_map_query)]
|
||||
|
@ -258,10 +261,10 @@ pub trait DefDatabase:
|
|||
// endregion:attrs
|
||||
|
||||
#[salsa::invoke(LangItems::lang_item_query)]
|
||||
fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option<LangItemTarget>;
|
||||
fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option<LangItemTarget>;
|
||||
|
||||
#[salsa::invoke(ImportMap::import_map_query)]
|
||||
fn import_map(&self, krate: CrateId) -> Arc<ImportMap>;
|
||||
#[salsa::invoke_actual(ImportMap::import_map_query)]
|
||||
fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
|
||||
|
||||
// region:visibilities
|
||||
|
||||
|
@ -277,23 +280,25 @@ pub trait DefDatabase:
|
|||
|
||||
// endregion:visibilities
|
||||
|
||||
#[salsa::invoke(LangItems::crate_lang_items_query)]
|
||||
fn crate_lang_items(&self, krate: CrateId) -> Option<Arc<LangItems>>;
|
||||
#[salsa::invoke_actual(LangItems::crate_lang_items_query)]
|
||||
fn crate_lang_items(&self, krate: Crate) -> Option<Arc<LangItems>>;
|
||||
|
||||
#[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
|
||||
fn notable_traits_in_deps(&self, krate: CrateId) -> Arc<[Arc<[TraitId]>]>;
|
||||
#[salsa::invoke(crate::lang_item::crate_notable_traits)]
|
||||
fn crate_notable_traits(&self, krate: CrateId) -> Option<Arc<[TraitId]>>;
|
||||
#[salsa::invoke_actual(crate::lang_item::notable_traits_in_deps)]
|
||||
fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
|
||||
#[salsa::invoke_actual(crate::lang_item::crate_notable_traits)]
|
||||
fn crate_notable_traits(&self, krate: Crate) -> Option<Arc<[TraitId]>>;
|
||||
|
||||
fn crate_supports_no_std(&self, crate_id: CrateId) -> bool;
|
||||
#[salsa::invoke_actual(crate_supports_no_std)]
|
||||
fn crate_supports_no_std(&self, crate_id: Crate) -> bool;
|
||||
|
||||
fn include_macro_invoc(&self, crate_id: CrateId) -> Arc<[(MacroCallId, EditionedFileId)]>;
|
||||
#[salsa::invoke_actual(include_macro_invoc)]
|
||||
fn include_macro_invoc(&self, crate_id: Crate) -> Arc<[(MacroCallId, EditionedFileId)]>;
|
||||
}
|
||||
|
||||
// return: macro call id and include file id
|
||||
fn include_macro_invoc(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Arc<[(MacroCallId, EditionedFileId)]> {
|
||||
db.crate_def_map(krate)
|
||||
.modules
|
||||
|
@ -307,8 +312,8 @@ fn include_macro_invoc(
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool {
|
||||
let file = db.crate_graph()[crate_id].root_file_id();
|
||||
fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool {
|
||||
let file = crate_id.data(db).root_file_id();
|
||||
let item_tree = db.file_item_tree(file.into());
|
||||
let attrs = item_tree.raw_attrs(AttrOwner::TopLevel);
|
||||
for attr in &**attrs {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::cell::OnceCell;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use cfg::CfgOptions;
|
||||
use drop_bomb::DropBomb;
|
||||
use hir_expand::{
|
||||
|
@ -44,7 +44,7 @@ impl Expander {
|
|||
module,
|
||||
recursion_depth: 0,
|
||||
recursion_limit,
|
||||
cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
|
||||
cfg_options: Arc::clone(module.krate.cfg_options(db)),
|
||||
span_map: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ impl Expander {
|
|||
self.span_map.get_or_init(|| db.span_map(self.current_file_id))
|
||||
}
|
||||
|
||||
pub fn krate(&self) -> CrateId {
|
||||
pub fn krate(&self) -> Crate {
|
||||
self.module.krate
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ impl Body {
|
|||
let item_tree = f.id.item_tree(db);
|
||||
let func = &item_tree[f.id.value];
|
||||
let krate = f.container.module(db).krate;
|
||||
let crate_graph = db.crate_graph();
|
||||
(
|
||||
param_list,
|
||||
(0..func.params.len()).map(move |idx| {
|
||||
|
@ -99,7 +98,7 @@ impl Body {
|
|||
Idx::from_raw(RawIdx::from(idx as u32)),
|
||||
),
|
||||
)
|
||||
.is_cfg_enabled(&crate_graph[krate].cfg_options)
|
||||
.is_cfg_enabled(krate.cfg_options(db))
|
||||
}),
|
||||
)
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ mod asm;
|
|||
|
||||
use std::mem;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use either::Either;
|
||||
use hir_expand::{
|
||||
mod_path::tool_path,
|
||||
|
@ -50,7 +50,7 @@ use crate::{
|
|||
item_scope::BuiltinShadowMode,
|
||||
lang_item::LangItem,
|
||||
lower::LowerCtx,
|
||||
nameres::{DefMap, MacroSubNs},
|
||||
nameres::{DefMap, LocalDefMap, MacroSubNs},
|
||||
path::{GenericArgs, Path},
|
||||
type_ref::{Mutability, Rawness, TypeRef},
|
||||
AdtId, BlockId, BlockLoc, ConstBlockLoc, DefWithBodyId, MacroId, ModuleDefId, UnresolvedMacro,
|
||||
|
@ -64,7 +64,7 @@ pub(super) fn lower_body(
|
|||
expander: Expander,
|
||||
parameters: Option<(ast::ParamList, impl Iterator<Item = bool>)>,
|
||||
body: Option<ast::Expr>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
is_async_fn: bool,
|
||||
) -> (Body, BodySourceMap) {
|
||||
// We cannot leave the root span map empty and let any identifier from it be treated as root,
|
||||
|
@ -189,7 +189,7 @@ pub(super) fn lower(
|
|||
owner: ExprStoreOwnerId,
|
||||
expander: Expander,
|
||||
body: Option<ast::Expr>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap) {
|
||||
// We cannot leave the root span map empty and let any identifier from it be treated as root,
|
||||
// because when inside nested macros `SyntaxContextId`s from the outer macro will be interleaved
|
||||
|
@ -214,8 +214,9 @@ struct ExprCollector<'a> {
|
|||
expander: Expander,
|
||||
owner: ExprStoreOwnerId,
|
||||
def_map: Arc<DefMap>,
|
||||
local_def_map: Arc<LocalDefMap>,
|
||||
ast_id_map: Arc<AstIdMap>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
store: ExpressionStoreBuilder,
|
||||
source_map: ExpressionStoreSourceMap,
|
||||
|
||||
|
@ -327,14 +328,16 @@ impl ExprCollector<'_> {
|
|||
db: &dyn DefDatabase,
|
||||
owner: ExprStoreOwnerId,
|
||||
expander: Expander,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
span_map: Option<Arc<ExpansionSpanMap>>,
|
||||
) -> ExprCollector<'_> {
|
||||
let (def_map, local_def_map) = expander.module.local_def_map(db);
|
||||
ExprCollector {
|
||||
db,
|
||||
owner,
|
||||
krate,
|
||||
def_map: expander.module.def_map(db),
|
||||
def_map,
|
||||
local_def_map,
|
||||
source_map: ExpressionStoreSourceMap::default(),
|
||||
ast_id_map: db.ast_id_map(expander.current_file_id()),
|
||||
store: ExpressionStoreBuilder::default(),
|
||||
|
@ -1306,6 +1309,7 @@ impl ExprCollector<'_> {
|
|||
None => self.expander.enter_expand(self.db, mcall, |path| {
|
||||
self.def_map
|
||||
.resolve_path(
|
||||
&self.local_def_map,
|
||||
self.db,
|
||||
module,
|
||||
path,
|
||||
|
@ -1608,6 +1612,7 @@ impl ExprCollector<'_> {
|
|||
// This could also be a single-segment path pattern. To
|
||||
// decide that, we need to try resolving the name.
|
||||
let (resolved, _) = self.def_map.resolve_path(
|
||||
&self.local_def_map,
|
||||
self.db,
|
||||
self.expander.module.local_id,
|
||||
&name.clone().into(),
|
||||
|
|
|
@ -293,7 +293,7 @@ impl SsrError {
|
|||
assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]);
|
||||
expect![[r#"
|
||||
fn main() -> () {
|
||||
_ = $crate::error::SsrError::new(
|
||||
_ = ra_test_fixture::error::SsrError::new(
|
||||
builtin#lang(Arguments::new_v1_formatted)(
|
||||
&[
|
||||
"Failed to resolve path `", "`",
|
||||
|
@ -353,7 +353,7 @@ fn f(a: i32, b: u32) -> String {
|
|||
expect![[r#"
|
||||
fn f(a: i32, b: u32) -> String {
|
||||
{
|
||||
$crate::panicking::panic_fmt(
|
||||
core::panicking::panic_fmt(
|
||||
builtin#lang(Arguments::new_v1_formatted)(
|
||||
&[
|
||||
"cc",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{cell::Cell, cmp::Ordering, iter};
|
||||
|
||||
use base_db::{CrateId, CrateOrigin, LangCrateOrigin};
|
||||
use base_db::{Crate, CrateOrigin, LangCrateOrigin};
|
||||
use hir_expand::{
|
||||
name::{AsName, Name},
|
||||
Lookup,
|
||||
|
@ -50,7 +50,7 @@ pub fn find_path(
|
|||
prefix: prefix_kind,
|
||||
cfg,
|
||||
ignore_local_imports,
|
||||
is_std_item: db.crate_graph()[item_module.krate()].origin.is_lang(),
|
||||
is_std_item: item_module.krate().data(db).origin.is_lang(),
|
||||
from,
|
||||
from_def_map: &from.def_map(db),
|
||||
fuel: Cell::new(FIND_PATH_FUEL),
|
||||
|
@ -174,9 +174,9 @@ fn find_path_for_module(
|
|||
}
|
||||
// - otherwise if the item is the crate root of a dependency crate, return the name from the extern prelude
|
||||
|
||||
let root_def_map = ctx.from.derive_crate_root().def_map(ctx.db);
|
||||
let root_local_def_map = ctx.from.derive_crate_root().local_def_map(ctx.db).1;
|
||||
// rev here so we prefer looking at renamed extern decls first
|
||||
for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude().rev() {
|
||||
for (name, (def_id, _extern_crate)) in root_local_def_map.extern_prelude().rev() {
|
||||
if crate_root != def_id {
|
||||
continue;
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ fn calculate_best_path(
|
|||
// too (unless we can't name it at all). It could *also* be (re)exported by the same crate
|
||||
// that wants to import it here, but we always prefer to use the external path here.
|
||||
|
||||
ctx.db.crate_graph()[ctx.from.krate].dependencies.iter().for_each(|dep| {
|
||||
ctx.from.krate.data(ctx.db).dependencies.iter().for_each(|dep| {
|
||||
find_in_dep(ctx, visited_modules, item, max_len, best_choice, dep.crate_id)
|
||||
});
|
||||
}
|
||||
|
@ -373,11 +373,10 @@ fn find_in_sysroot(
|
|||
max_len: usize,
|
||||
best_choice: &mut Option<Choice>,
|
||||
) {
|
||||
let crate_graph = ctx.db.crate_graph();
|
||||
let dependencies = &crate_graph[ctx.from.krate].dependencies;
|
||||
let dependencies = &ctx.from.krate.data(ctx.db).dependencies;
|
||||
let mut search = |lang, best_choice: &mut _| {
|
||||
if let Some(dep) = dependencies.iter().filter(|it| it.is_sysroot()).find(|dep| {
|
||||
match crate_graph[dep.crate_id].origin {
|
||||
match dep.crate_id.data(ctx.db).origin {
|
||||
CrateOrigin::Lang(l) => l == lang,
|
||||
_ => false,
|
||||
}
|
||||
|
@ -419,7 +418,7 @@ fn find_in_dep(
|
|||
item: ItemInNs,
|
||||
max_len: usize,
|
||||
best_choice: &mut Option<Choice>,
|
||||
dep: CrateId,
|
||||
dep: Crate,
|
||||
) {
|
||||
let import_map = ctx.db.import_map(dep);
|
||||
let Some(import_info_for) = import_map.import_info_for(item) else {
|
||||
|
@ -688,9 +687,10 @@ mod tests {
|
|||
})
|
||||
.unwrap();
|
||||
|
||||
let def_map = module.def_map(&db);
|
||||
let (def_map, local_def_map) = module.local_def_map(&db);
|
||||
let resolved = def_map
|
||||
.resolve_path(
|
||||
&local_def_map,
|
||||
&db,
|
||||
module.local_id,
|
||||
&mod_path,
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::{
|
|||
expander::Expander,
|
||||
item_tree::{AttrOwner, FileItemTreeId, GenericModItem, GenericsItemTreeNode, ItemTree},
|
||||
lower::LowerCtx,
|
||||
nameres::{DefMap, MacroSubNs},
|
||||
nameres::{DefMap, LocalDefMap, MacroSubNs},
|
||||
path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path},
|
||||
type_ref::{
|
||||
ArrayType, ConstRef, FnType, LifetimeRef, PathId, RefType, TypeBound, TypeRef, TypeRefId,
|
||||
|
@ -313,8 +313,7 @@ impl GenericParams {
|
|||
let _p = tracing::info_span!("generic_params_query").entered();
|
||||
|
||||
let krate = def.krate(db);
|
||||
let cfg_options = db.crate_graph();
|
||||
let cfg_options = &cfg_options[krate].cfg_options;
|
||||
let cfg_options = &krate.cfg_options(db);
|
||||
|
||||
// Returns the generic parameters that are enabled under the current `#[cfg]` options
|
||||
let enabled_params =
|
||||
|
@ -413,7 +412,12 @@ impl GenericParams {
|
|||
&mut types_source_maps,
|
||||
&mut expander,
|
||||
&mut || {
|
||||
(module.def_map(db), Expander::new(db, loc.id.file_id(), module))
|
||||
let (def_map, local_def_map) = module.local_def_map(db);
|
||||
(
|
||||
def_map,
|
||||
local_def_map,
|
||||
Expander::new(db, loc.id.file_id(), module),
|
||||
)
|
||||
},
|
||||
param,
|
||||
&item.types_map,
|
||||
|
@ -626,8 +630,8 @@ impl GenericParamsCollector {
|
|||
generics_types_map: &mut TypesMap,
|
||||
generics_types_source_map: &mut TypesSourceMap,
|
||||
// FIXME: Change this back to `LazyCell` if https://github.com/rust-lang/libs-team/issues/429 is accepted.
|
||||
exp: &mut Option<(Arc<DefMap>, Expander)>,
|
||||
exp_fill: &mut dyn FnMut() -> (Arc<DefMap>, Expander),
|
||||
exp: &mut Option<(Arc<DefMap>, Arc<LocalDefMap>, Expander)>,
|
||||
exp_fill: &mut dyn FnMut() -> (Arc<DefMap>, Arc<LocalDefMap>, Expander),
|
||||
type_ref: TypeRefId,
|
||||
types_map: &TypesMap,
|
||||
types_source_map: &TypesSourceMap,
|
||||
|
@ -657,12 +661,13 @@ impl GenericParamsCollector {
|
|||
|
||||
if let TypeRef::Macro(mc) = type_ref {
|
||||
let macro_call = mc.to_node(db.upcast());
|
||||
let (def_map, expander) = exp.get_or_insert_with(&mut *exp_fill);
|
||||
let (def_map, local_def_map, expander) = exp.get_or_insert_with(&mut *exp_fill);
|
||||
|
||||
let module = expander.module.local_id;
|
||||
let resolver = |path: &_| {
|
||||
def_map
|
||||
.resolve_path(
|
||||
local_def_map,
|
||||
db,
|
||||
module,
|
||||
path,
|
||||
|
@ -690,7 +695,7 @@ impl GenericParamsCollector {
|
|||
¯o_types_map,
|
||||
¯o_types_source_map,
|
||||
);
|
||||
exp.get_or_insert_with(&mut *exp_fill).1.exit(mark);
|
||||
exp.get_or_insert_with(&mut *exp_fill).2.exit(mark);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use fst::{raw::IndexedValue, Automaton, Streamer};
|
||||
use hir_expand::name::Name;
|
||||
use itertools::Itertools;
|
||||
|
@ -78,7 +78,7 @@ impl ImportMap {
|
|||
out
|
||||
}
|
||||
|
||||
pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<Self> {
|
||||
pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc<Self> {
|
||||
let _p = tracing::info_span!("import_map_query").entered();
|
||||
|
||||
let map = Self::collect_import_map(db, krate);
|
||||
|
@ -129,7 +129,7 @@ impl ImportMap {
|
|||
self.item_to_info_map.get(&item).map(|(info, _)| &**info)
|
||||
}
|
||||
|
||||
fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMapIndex {
|
||||
fn collect_import_map(db: &dyn DefDatabase, krate: Crate) -> ImportMapIndex {
|
||||
let _p = tracing::info_span!("collect_import_map").entered();
|
||||
|
||||
let def_map = db.crate_def_map(krate);
|
||||
|
@ -400,15 +400,13 @@ impl Query {
|
|||
/// This returns a list of items that could be imported from dependencies of `krate`.
|
||||
pub fn search_dependencies(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
query: &Query,
|
||||
) -> FxHashSet<ItemInNs> {
|
||||
let _p = tracing::info_span!("search_dependencies", ?query).entered();
|
||||
|
||||
let graph = db.crate_graph();
|
||||
|
||||
let import_maps: Vec<_> =
|
||||
graph[krate].dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect();
|
||||
krate.data(db).dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect();
|
||||
|
||||
let mut op = fst::map::OpBuilder::new();
|
||||
|
||||
|
@ -512,11 +510,13 @@ mod tests {
|
|||
expect: Expect,
|
||||
) {
|
||||
let db = TestDB::with_files(ra_fixture);
|
||||
let crate_graph = db.crate_graph();
|
||||
let krate = crate_graph
|
||||
let all_crates = db.all_crates();
|
||||
let krate = all_crates
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|&krate| {
|
||||
crate_graph[krate]
|
||||
krate
|
||||
.extra_data(&db)
|
||||
.display_name
|
||||
.as_ref()
|
||||
.is_some_and(|it| it.crate_name().as_str() == crate_name)
|
||||
|
@ -545,7 +545,7 @@ mod tests {
|
|||
|
||||
Some(format!(
|
||||
"{}::{} ({})\n",
|
||||
crate_graph[dependency_krate].display_name.as_ref()?,
|
||||
dependency_krate.extra_data(&db).display_name.as_ref()?,
|
||||
path,
|
||||
mark
|
||||
))
|
||||
|
@ -590,12 +590,13 @@ mod tests {
|
|||
|
||||
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
|
||||
let db = TestDB::with_files(ra_fixture);
|
||||
let crate_graph = db.crate_graph();
|
||||
let all_crates = db.all_crates();
|
||||
|
||||
let actual = crate_graph
|
||||
let actual = all_crates
|
||||
.iter()
|
||||
.copied()
|
||||
.filter_map(|krate| {
|
||||
let cdata = &crate_graph[krate];
|
||||
let cdata = &krate.extra_data(&db);
|
||||
let name = cdata.display_name.as_ref()?;
|
||||
|
||||
let map = db.import_map(krate);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
|
||||
use indexmap::map::Entry;
|
||||
use itertools::Itertools;
|
||||
|
@ -916,7 +916,7 @@ impl ItemInNs {
|
|||
}
|
||||
|
||||
/// Returns the crate defining this item (or `None` if `self` is built-in).
|
||||
pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> {
|
||||
pub fn krate(&self, db: &dyn DefDatabase) -> Option<Crate> {
|
||||
match self {
|
||||
ItemInNs::Types(id) | ItemInNs::Values(id) => id.module(db).map(|m| m.krate),
|
||||
ItemInNs::Macros(id) => Some(id.module(db).krate),
|
||||
|
|
|
@ -44,7 +44,7 @@ use std::{
|
|||
};
|
||||
|
||||
use ast::{AstNode, StructKind};
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use either::Either;
|
||||
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
|
||||
use intern::{Interned, Symbol};
|
||||
|
@ -202,7 +202,7 @@ impl ItemTree {
|
|||
}
|
||||
|
||||
/// Returns the inner attributes of the source file.
|
||||
pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
|
||||
pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
|
||||
Attrs::filter(
|
||||
db,
|
||||
krate,
|
||||
|
@ -214,7 +214,7 @@ impl ItemTree {
|
|||
self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
|
||||
}
|
||||
|
||||
pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
|
||||
pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs {
|
||||
Attrs::filter(db, krate, self.raw_attrs(of).clone())
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_hash::FxHashMap;
|
|||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase, path::Path, AdtId, AssocItemId, AttrDefId, CrateId, EnumId, EnumVariantId,
|
||||
db::DefDatabase, path::Path, AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId,
|
||||
FunctionId, ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
|
||||
};
|
||||
|
||||
|
@ -96,7 +96,7 @@ impl LangItems {
|
|||
/// Salsa query. This will look for lang items in a specific crate.
|
||||
pub(crate) fn crate_lang_items_query(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Option<Arc<LangItems>> {
|
||||
let _p = tracing::info_span!("crate_lang_items_query").entered();
|
||||
|
||||
|
@ -175,7 +175,7 @@ impl LangItems {
|
|||
/// traversing its dependencies.
|
||||
pub(crate) fn lang_item_query(
|
||||
db: &dyn DefDatabase,
|
||||
start_crate: CrateId,
|
||||
start_crate: Crate,
|
||||
item: LangItem,
|
||||
) -> Option<LangItemTarget> {
|
||||
let _p = tracing::info_span!("lang_item_query").entered();
|
||||
|
@ -184,10 +184,7 @@ impl LangItems {
|
|||
{
|
||||
return Some(target);
|
||||
}
|
||||
db.crate_graph()[start_crate]
|
||||
.dependencies
|
||||
.iter()
|
||||
.find_map(|dep| db.lang_item(dep.crate_id, item))
|
||||
start_crate.data(db).dependencies.iter().find_map(|dep| db.lang_item(dep.crate_id, item))
|
||||
}
|
||||
|
||||
fn collect_lang_item<T>(
|
||||
|
@ -209,19 +206,14 @@ pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option<LangIte
|
|||
db.attrs(item).lang_item()
|
||||
}
|
||||
|
||||
pub(crate) fn notable_traits_in_deps(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
) -> Arc<[Arc<[TraitId]>]> {
|
||||
pub(crate) fn notable_traits_in_deps(db: &dyn DefDatabase, krate: Crate) -> Arc<[Arc<[TraitId]>]> {
|
||||
let _p = tracing::info_span!("notable_traits_in_deps", ?krate).entered();
|
||||
let crate_graph = db.crate_graph();
|
||||
|
||||
Arc::from_iter(
|
||||
crate_graph.transitive_deps(krate).filter_map(|krate| db.crate_notable_traits(krate)),
|
||||
db.transitive_deps(krate).into_iter().filter_map(|krate| db.crate_notable_traits(krate)),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: CrateId) -> Option<Arc<[TraitId]>> {
|
||||
pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Arc<[TraitId]>> {
|
||||
let _p = tracing::info_span!("crate_notable_traits", ?krate).entered();
|
||||
|
||||
let mut traits = Vec::new();
|
||||
|
@ -290,17 +282,12 @@ impl LangItem {
|
|||
Self::from_symbol(name.symbol())
|
||||
}
|
||||
|
||||
pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option<Path> {
|
||||
pub fn path(&self, db: &dyn DefDatabase, start_crate: Crate) -> Option<Path> {
|
||||
let t = db.lang_item(start_crate, *self)?;
|
||||
Some(Path::LangItem(t, None))
|
||||
}
|
||||
|
||||
pub fn ty_rel_path(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
start_crate: CrateId,
|
||||
seg: Name,
|
||||
) -> Option<Path> {
|
||||
pub fn ty_rel_path(&self, db: &dyn DefDatabase, start_crate: Crate, seg: Name) -> Option<Path> {
|
||||
let t = db.lang_item(start_crate, *self)?;
|
||||
Some(Path::LangItem(t, Some(seg)))
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ mod test_db;
|
|||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use base_db::{impl_intern_key, CrateId};
|
||||
use base_db::{impl_intern_key, Crate};
|
||||
use hir_expand::{
|
||||
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
|
||||
db::ExpandDatabase,
|
||||
|
@ -99,10 +99,10 @@ use crate::{
|
|||
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules,
|
||||
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
|
||||
},
|
||||
nameres::LocalDefMap,
|
||||
};
|
||||
|
||||
type FxIndexMap<K, V> =
|
||||
indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
|
||||
type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
|
||||
/// A wrapper around three booleans
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
|
||||
pub struct ImportPathConfig {
|
||||
|
@ -338,7 +338,7 @@ pub struct ConstBlockLoc {
|
|||
/// A `ModuleId` that is always a crate's root module.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct CrateRootModuleId {
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
}
|
||||
|
||||
impl CrateRootModuleId {
|
||||
|
@ -346,7 +346,11 @@ impl CrateRootModuleId {
|
|||
db.crate_def_map(self.krate)
|
||||
}
|
||||
|
||||
pub fn krate(self) -> CrateId {
|
||||
pub(crate) fn local_def_map(&self, db: &dyn DefDatabase) -> (Arc<DefMap>, Arc<LocalDefMap>) {
|
||||
db.crate_local_def_map(self.krate)
|
||||
}
|
||||
|
||||
pub fn krate(self) -> Crate {
|
||||
self.krate
|
||||
}
|
||||
}
|
||||
|
@ -374,8 +378,8 @@ impl From<CrateRootModuleId> for ModuleDefId {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<CrateId> for CrateRootModuleId {
|
||||
fn from(krate: CrateId) -> Self {
|
||||
impl From<Crate> for CrateRootModuleId {
|
||||
fn from(krate: Crate) -> Self {
|
||||
CrateRootModuleId { krate }
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +398,7 @@ impl TryFrom<ModuleId> for CrateRootModuleId {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ModuleId {
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
/// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
|
||||
/// `BlockId` of that block expression. If `None`, this module is part of the crate-level
|
||||
/// `DefMap` of `krate`.
|
||||
|
@ -411,11 +415,22 @@ impl ModuleId {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (Arc<DefMap>, Arc<LocalDefMap>) {
|
||||
match self.block {
|
||||
Some(block) => (db.block_def_map(block), self.only_local_def_map(db)),
|
||||
None => db.crate_local_def_map(self.krate),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> Arc<LocalDefMap> {
|
||||
db.crate_local_def_map(self.krate).1
|
||||
}
|
||||
|
||||
pub fn crate_def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> {
|
||||
db.crate_def_map(self.krate)
|
||||
}
|
||||
|
||||
pub fn krate(self) -> CrateId {
|
||||
pub fn krate(self) -> Crate {
|
||||
self.krate
|
||||
}
|
||||
|
||||
|
@ -982,7 +997,7 @@ impl From<CallableDefId> for ModuleDefId {
|
|||
}
|
||||
|
||||
impl CallableDefId {
|
||||
pub fn krate(self, db: &dyn DefDatabase) -> CrateId {
|
||||
pub fn krate(self, db: &dyn DefDatabase) -> Crate {
|
||||
match self {
|
||||
CallableDefId::FunctionId(f) => f.krate(db),
|
||||
CallableDefId::StructId(s) => s.krate(db),
|
||||
|
@ -1119,7 +1134,7 @@ pub trait HasModule {
|
|||
/// Returns the crate this thing is defined within.
|
||||
#[inline]
|
||||
#[doc(alias = "crate")]
|
||||
fn krate(&self, db: &dyn DefDatabase) -> CrateId {
|
||||
fn krate(&self, db: &dyn DefDatabase) -> Crate {
|
||||
self.module(db).krate
|
||||
}
|
||||
}
|
||||
|
@ -1367,7 +1382,7 @@ pub trait AsMacroCall {
|
|||
fn as_call_id(
|
||||
&self,
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||
) -> Option<MacroCallId> {
|
||||
self.as_call_id_with_errors(db, krate, resolver).ok()?.value
|
||||
|
@ -1376,7 +1391,7 @@ pub trait AsMacroCall {
|
|||
fn as_call_id_with_errors(
|
||||
&self,
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
|
||||
}
|
||||
|
@ -1385,7 +1400,7 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
|
|||
fn as_call_id_with_errors(
|
||||
&self,
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
||||
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
|
||||
|
@ -1442,7 +1457,7 @@ fn macro_call_as_call_id(
|
|||
call: &AstIdWithPath<ast::MacroCall>,
|
||||
call_site: SyntaxContextId,
|
||||
expand_to: ExpandTo,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
||||
macro_call_as_call_id_with_eager(
|
||||
|
@ -1464,7 +1479,7 @@ fn macro_call_as_call_id_with_eager(
|
|||
path: &path::ModPath,
|
||||
call_site: SyntaxContextId,
|
||||
expand_to: ExpandTo,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl FnOnce(&path::ModPath) -> Option<MacroDefId>,
|
||||
eager_resolver: impl Fn(&path::ModPath) -> Option<MacroDefId>,
|
||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
||||
|
|
|
@ -376,4 +376,8 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
|
|||
panic!("got invalid macro input: {:?}", parse.errors());
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
|
||||
other.as_any().type_id() == std::any::TypeId::of::<Self>()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ mod tests;
|
|||
|
||||
use std::ops::Deref;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_expand::{
|
||||
name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ use la_arena::Arena;
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use span::{Edition, EditionedFileId, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID};
|
||||
use stdx::format_to;
|
||||
use syntax::{ast, AstNode, SmolStr, SyntaxNode};
|
||||
use syntax::{ast, AstNode, SmolStr, SyntaxNode, ToSmolStr};
|
||||
use triomphe::Arc;
|
||||
use tt::TextRange;
|
||||
|
||||
|
@ -95,6 +95,39 @@ const PREDEFINED_TOOLS: &[SmolStr] = &[
|
|||
SmolStr::new_static("rust_analyzer"),
|
||||
];
|
||||
|
||||
/// Parts of the def map that are only needed when analyzing code in the same crate.
|
||||
///
|
||||
/// There are some data in the def map (e.g. extern prelude) that is only needed when analyzing
|
||||
/// things in the same crate (and maybe in the IDE layer), e.g. the extern prelude. If we put
|
||||
/// it in the DefMap dependant DefMaps will be invalidated when they change (e.g. when we add
|
||||
/// a dependency to the crate). Instead we split them out of the DefMap into a LocalDefMap struct.
|
||||
/// `crate_local_def_map()` returns both, and `crate_def_map()` returns only the external-relevant
|
||||
/// DefMap.
|
||||
#[derive(Debug, PartialEq, Eq, Default)]
|
||||
pub struct LocalDefMap {
|
||||
// FIXME: There are probably some other things that could be here, but this is less severe and you
|
||||
// need to be careful with things that block def maps also have.
|
||||
/// The extern prelude which contains all root modules of external crates that are in scope.
|
||||
extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
|
||||
}
|
||||
|
||||
impl LocalDefMap {
|
||||
pub(crate) const EMPTY: &Self =
|
||||
&Self { extern_prelude: FxIndexMap::with_hasher(rustc_hash::FxBuildHasher) };
|
||||
|
||||
fn shrink_to_fit(&mut self) {
|
||||
let Self { extern_prelude } = self;
|
||||
extern_prelude.shrink_to_fit();
|
||||
}
|
||||
|
||||
pub(crate) fn extern_prelude(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_
|
||||
{
|
||||
self.extern_prelude.iter().map(|(name, &def)| (name, def))
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains the results of (early) name resolution.
|
||||
///
|
||||
/// A `DefMap` stores the module tree and the definitions that are in scope in every module after
|
||||
|
@ -107,7 +140,7 @@ const PREDEFINED_TOOLS: &[SmolStr] = &[
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct DefMap {
|
||||
/// The crate this `DefMap` belongs to.
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
/// When this is a block def map, this will hold the block id of the block and module that
|
||||
/// contains this block.
|
||||
block: Option<BlockInfo>,
|
||||
|
@ -141,9 +174,6 @@ pub struct DefMap {
|
|||
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct DefMapCrateData {
|
||||
/// The extern prelude which contains all root modules of external crates that are in scope.
|
||||
extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
|
||||
|
||||
/// Side table for resolving derive helpers.
|
||||
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
||||
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
|
||||
|
@ -166,7 +196,6 @@ struct DefMapCrateData {
|
|||
impl DefMapCrateData {
|
||||
fn new(edition: Edition) -> Self {
|
||||
Self {
|
||||
extern_prelude: FxIndexMap::default(),
|
||||
exported_derives: FxHashMap::default(),
|
||||
fn_proc_macro_mapping: FxHashMap::default(),
|
||||
registered_attrs: Vec::new(),
|
||||
|
@ -182,7 +211,6 @@ impl DefMapCrateData {
|
|||
|
||||
fn shrink_to_fit(&mut self) {
|
||||
let Self {
|
||||
extern_prelude,
|
||||
exported_derives,
|
||||
fn_proc_macro_mapping,
|
||||
registered_attrs,
|
||||
|
@ -194,7 +222,6 @@ impl DefMapCrateData {
|
|||
edition: _,
|
||||
recursion_limit: _,
|
||||
} = self;
|
||||
extern_prelude.shrink_to_fit();
|
||||
exported_derives.shrink_to_fit();
|
||||
fn_proc_macro_mapping.shrink_to_fit();
|
||||
registered_attrs.shrink_to_fit();
|
||||
|
@ -219,11 +246,11 @@ struct BlockRelativeModuleId {
|
|||
}
|
||||
|
||||
impl BlockRelativeModuleId {
|
||||
fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
|
||||
fn def_map(self, db: &dyn DefDatabase, krate: Crate) -> Arc<DefMap> {
|
||||
self.into_module(krate).def_map(db)
|
||||
}
|
||||
|
||||
fn into_module(self, krate: CrateId) -> ModuleId {
|
||||
fn into_module(self, krate: Crate) -> ModuleId {
|
||||
ModuleId { krate, block: self.block, local_id: self.local_id }
|
||||
}
|
||||
|
||||
|
@ -337,11 +364,25 @@ impl DefMap {
|
|||
self.data.edition
|
||||
}
|
||||
|
||||
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: CrateId) -> Arc<DefMap> {
|
||||
let crate_graph = db.crate_graph();
|
||||
let krate = &crate_graph[crate_id];
|
||||
let name = krate.display_name.as_deref().map(Symbol::as_str).unwrap_or_default();
|
||||
let _p = tracing::info_span!("crate_def_map_query", ?name).entered();
|
||||
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, crate_id: Crate) -> Arc<DefMap> {
|
||||
db.crate_local_def_map(crate_id).0
|
||||
}
|
||||
|
||||
pub(crate) fn crate_local_def_map_query(
|
||||
db: &dyn DefDatabase,
|
||||
crate_id: Crate,
|
||||
) -> (Arc<DefMap>, Arc<LocalDefMap>) {
|
||||
let krate = crate_id.data(db);
|
||||
let _p = tracing::info_span!(
|
||||
"crate_def_map_query",
|
||||
name=?crate_id
|
||||
.extra_data(db)
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map(|it| it.crate_name().to_smolstr())
|
||||
.unwrap_or_default()
|
||||
)
|
||||
.entered();
|
||||
|
||||
let module_data = ModuleData::new(
|
||||
ModuleOrigin::CrateRoot { definition: krate.root_file_id() },
|
||||
|
@ -354,10 +395,14 @@ impl DefMap {
|
|||
module_data,
|
||||
None,
|
||||
);
|
||||
let def_map =
|
||||
collector::collect_defs(db, def_map, TreeId::new(krate.root_file_id().into(), None));
|
||||
let (def_map, local_def_map) = collector::collect_defs(
|
||||
db,
|
||||
def_map,
|
||||
TreeId::new(krate.root_file_id().into(), None),
|
||||
None,
|
||||
);
|
||||
|
||||
Arc::new(def_map)
|
||||
(Arc::new(def_map), Arc::new(local_def_map))
|
||||
}
|
||||
|
||||
pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
|
||||
|
@ -370,10 +415,10 @@ impl DefMap {
|
|||
let module_data =
|
||||
ModuleData::new(ModuleOrigin::BlockExpr { block: ast_id, id: block_id }, visibility);
|
||||
|
||||
let parent_map = module.def_map(db);
|
||||
let (crate_map, crate_local_map) = db.crate_local_def_map(module.krate);
|
||||
let def_map = DefMap::empty(
|
||||
module.krate,
|
||||
parent_map.data.clone(),
|
||||
crate_map.data.clone(),
|
||||
module_data,
|
||||
Some(BlockInfo {
|
||||
block: block_id,
|
||||
|
@ -381,13 +426,17 @@ impl DefMap {
|
|||
}),
|
||||
);
|
||||
|
||||
let def_map =
|
||||
collector::collect_defs(db, def_map, TreeId::new(ast_id.file_id, Some(block_id)));
|
||||
let (def_map, _) = collector::collect_defs(
|
||||
db,
|
||||
def_map,
|
||||
TreeId::new(ast_id.file_id, Some(block_id)),
|
||||
Some(crate_local_map),
|
||||
);
|
||||
Arc::new(def_map)
|
||||
}
|
||||
|
||||
fn empty(
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
crate_data: Arc<DefMapCrateData>,
|
||||
module_data: ModuleData,
|
||||
block: Option<BlockInfo>,
|
||||
|
@ -479,7 +528,7 @@ impl DefMap {
|
|||
self.data.fn_proc_macro_mapping.get(&id).copied()
|
||||
}
|
||||
|
||||
pub fn krate(&self) -> CrateId {
|
||||
pub fn krate(&self) -> Crate {
|
||||
self.krate
|
||||
}
|
||||
|
||||
|
@ -590,19 +639,13 @@ impl DefMap {
|
|||
self.prelude
|
||||
}
|
||||
|
||||
pub(crate) fn extern_prelude(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_
|
||||
{
|
||||
self.data.extern_prelude.iter().map(|(name, &def)| (name, def))
|
||||
}
|
||||
|
||||
pub(crate) fn macro_use_prelude(&self) -> &FxHashMap<Name, (MacroId, Option<ExternCrateId>)> {
|
||||
&self.macro_use_prelude
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
original_module: LocalModuleId,
|
||||
path: &ModPath,
|
||||
|
@ -610,6 +653,7 @@ impl DefMap {
|
|||
expected_macro_subns: Option<MacroSubNs>,
|
||||
) -> (PerNs, Option<usize>) {
|
||||
let res = self.resolve_path_fp_with_macro(
|
||||
local_def_map,
|
||||
db,
|
||||
ResolveMode::Other,
|
||||
original_module,
|
||||
|
@ -624,12 +668,14 @@ impl DefMap {
|
|||
/// points at the unresolved segments.
|
||||
pub(crate) fn resolve_path_locally(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
original_module: LocalModuleId,
|
||||
path: &ModPath,
|
||||
shadow: BuiltinShadowMode,
|
||||
) -> (PerNs, Option<usize>, ResolvePathResultPrefixInfo) {
|
||||
let res = self.resolve_path_fp_with_macro_single(
|
||||
local_def_map,
|
||||
db,
|
||||
ResolveMode::Other,
|
||||
original_module,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Post-nameres attribute resolution.
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_expand::{
|
||||
attrs::{Attr, AttrId, AttrInput},
|
||||
inert_attr_macro::find_builtin_attr_idx,
|
||||
|
@ -13,7 +13,7 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
db::DefDatabase,
|
||||
item_scope::BuiltinShadowMode,
|
||||
nameres::path_resolution::ResolveMode,
|
||||
nameres::{path_resolution::ResolveMode, LocalDefMap},
|
||||
path::{self, ModPath, PathKind},
|
||||
AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro,
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ pub enum ResolvedAttr {
|
|||
impl DefMap {
|
||||
pub(crate) fn resolve_attr_macro(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
original_module: LocalModuleId,
|
||||
ast_id: AstIdWithPath<ast::Item>,
|
||||
|
@ -42,6 +43,7 @@ impl DefMap {
|
|||
}
|
||||
|
||||
let resolved_res = self.resolve_path_fp_with_macro(
|
||||
local_def_map,
|
||||
db,
|
||||
ResolveMode::Other,
|
||||
original_module,
|
||||
|
@ -105,7 +107,7 @@ pub(super) fn attr_macro_as_call_id(
|
|||
db: &dyn DefDatabase,
|
||||
item_attr: &AstIdWithPath<ast::Item>,
|
||||
macro_attr: &Attr,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
def: MacroDefId,
|
||||
) -> MacroCallId {
|
||||
let arg = match macro_attr.input.as_deref() {
|
||||
|
@ -136,7 +138,7 @@ pub(super) fn derive_macro_as_call_id(
|
|||
derive_attr_index: AttrId,
|
||||
derive_pos: u32,
|
||||
call_site: SyntaxContextId,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&path::ModPath) -> Option<(MacroId, MacroDefId)>,
|
||||
derive_macro_id: MacroCallId,
|
||||
) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use std::{cmp::Ordering, iter, mem, ops::Not};
|
||||
|
||||
use base_db::{CrateId, CrateOrigin, Dependency, LangCrateOrigin};
|
||||
use base_db::{BuiltDependency, Crate, CrateOrigin, LangCrateOrigin};
|
||||
use cfg::{CfgAtom, CfgExpr, CfgOptions};
|
||||
use either::Either;
|
||||
use hir_expand::{
|
||||
|
@ -39,8 +39,8 @@ use crate::{
|
|||
mod_resolution::ModDir,
|
||||
path_resolution::ReachedFixedPoint,
|
||||
proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroDef, ProcMacroKind},
|
||||
sub_namespace_match, BuiltinShadowMode, DefMap, MacroSubNs, ModuleData, ModuleOrigin,
|
||||
ResolveMode,
|
||||
sub_namespace_match, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData,
|
||||
ModuleOrigin, ResolveMode,
|
||||
},
|
||||
path::{ImportAlias, ModPath, PathKind},
|
||||
per_ns::{Item, PerNs},
|
||||
|
@ -57,10 +57,14 @@ use crate::{
|
|||
const GLOB_RECURSION_LIMIT: usize = 100;
|
||||
const FIXED_POINT_LIMIT: usize = 8192;
|
||||
|
||||
pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap {
|
||||
let crate_graph = db.crate_graph();
|
||||
|
||||
let krate = &crate_graph[def_map.krate];
|
||||
pub(super) fn collect_defs(
|
||||
db: &dyn DefDatabase,
|
||||
def_map: DefMap,
|
||||
tree_id: TreeId,
|
||||
crate_local_def_map: Option<Arc<LocalDefMap>>,
|
||||
) -> (DefMap, LocalDefMap) {
|
||||
let krate = &def_map.krate.data(db);
|
||||
let cfg_options = def_map.krate.cfg_options(db);
|
||||
|
||||
// populate external prelude and dependency list
|
||||
let mut deps =
|
||||
|
@ -72,8 +76,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
|||
}
|
||||
|
||||
let proc_macros = if krate.is_proc_macro {
|
||||
db.proc_macros()
|
||||
.for_crate(def_map.krate, db.syntax_context(tree_id.file_id(), krate.edition))
|
||||
db.proc_macros_for_crate(def_map.krate)
|
||||
.and_then(|proc_macros| {
|
||||
proc_macros.list(db.syntax_context(tree_id.file_id(), krate.edition))
|
||||
})
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
Default::default()
|
||||
|
@ -82,13 +88,15 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
|||
let mut collector = DefCollector {
|
||||
db,
|
||||
def_map,
|
||||
local_def_map: LocalDefMap::default(),
|
||||
crate_local_def_map,
|
||||
deps,
|
||||
glob_imports: FxHashMap::default(),
|
||||
unresolved_imports: Vec::new(),
|
||||
indeterminate_imports: Vec::new(),
|
||||
unresolved_macros: Vec::new(),
|
||||
mod_dirs: FxHashMap::default(),
|
||||
cfg_options: &krate.cfg_options,
|
||||
cfg_options,
|
||||
proc_macros,
|
||||
from_glob_import: Default::default(),
|
||||
skip_attrs: Default::default(),
|
||||
|
@ -101,9 +109,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
|||
collector.seed_with_top_level();
|
||||
}
|
||||
collector.collect();
|
||||
let mut def_map = collector.finish();
|
||||
let (mut def_map, mut local_def_map) = collector.finish();
|
||||
def_map.shrink_to_fit();
|
||||
def_map
|
||||
local_def_map.shrink_to_fit();
|
||||
(def_map, local_def_map)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -205,8 +214,11 @@ enum MacroDirectiveKind {
|
|||
struct DefCollector<'a> {
|
||||
db: &'a dyn DefDatabase,
|
||||
def_map: DefMap,
|
||||
local_def_map: LocalDefMap,
|
||||
/// Set only in case of blocks.
|
||||
crate_local_def_map: Option<Arc<LocalDefMap>>,
|
||||
// The dependencies of the current crate, including optional deps like `test`.
|
||||
deps: FxHashMap<Name, Dependency>,
|
||||
deps: FxHashMap<Name, BuiltDependency>,
|
||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
|
||||
unresolved_imports: Vec<ImportDirective>,
|
||||
indeterminate_imports: Vec<(ImportDirective, PerNs)>,
|
||||
|
@ -238,8 +250,7 @@ impl DefCollector<'_> {
|
|||
fn seed_with_top_level(&mut self) {
|
||||
let _p = tracing::info_span!("seed_with_top_level").entered();
|
||||
|
||||
let crate_graph = self.db.crate_graph();
|
||||
let file_id = crate_graph[self.def_map.krate].root_file_id();
|
||||
let file_id = self.def_map.krate.data(self.db).root_file_id();
|
||||
let item_tree = self.db.file_item_tree(file_id.into());
|
||||
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
|
||||
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
||||
|
@ -310,20 +321,24 @@ impl DefCollector<'_> {
|
|||
// don't do pre-configured attribute resolution yet.
|
||||
// So here check if we are no_core / no_std and we are trying to add the
|
||||
// corresponding dep from the sysroot
|
||||
let skip = match crate_graph[dep.crate_id].origin {
|
||||
CrateOrigin::Lang(LangCrateOrigin::Core) => {
|
||||
crate_data.no_core && dep.is_sysroot()
|
||||
}
|
||||
CrateOrigin::Lang(LangCrateOrigin::Std) => {
|
||||
crate_data.no_std && dep.is_sysroot()
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
// Depending on the crate data of a dependency seems bad for incrementality, but
|
||||
// we only do that for sysroot crates (this is why the order of the `&&` is important)
|
||||
// - which are normally standard library crate, which realistically aren't going
|
||||
// to have their crate ID invalidated, because they stay on the same root file and
|
||||
// they're dependencies of everything else, so if some collision miraculously occurs
|
||||
// we will resolve it by disambiguating the other crate.
|
||||
let skip = dep.is_sysroot()
|
||||
&& match dep.crate_id.data(self.db).origin {
|
||||
CrateOrigin::Lang(LangCrateOrigin::Core) => crate_data.no_core,
|
||||
CrateOrigin::Lang(LangCrateOrigin::Std) => crate_data.no_std,
|
||||
_ => false,
|
||||
};
|
||||
if skip {
|
||||
continue;
|
||||
}
|
||||
|
||||
crate_data
|
||||
self.local_def_map
|
||||
.extern_prelude
|
||||
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
|
||||
}
|
||||
|
@ -494,7 +509,7 @@ impl DefCollector<'_> {
|
|||
|
||||
let krate = if self.def_map.data.no_std {
|
||||
Name::new_symbol_root(sym::core.clone())
|
||||
} else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std.clone()) {
|
||||
} else if self.local_def_map().extern_prelude().any(|(name, _)| *name == sym::std.clone()) {
|
||||
Name::new_symbol_root(sym::std.clone())
|
||||
} else {
|
||||
// If `std` does not exist for some reason, fall back to core. This mostly helps
|
||||
|
@ -518,8 +533,14 @@ impl DefCollector<'_> {
|
|||
[krate, Name::new_symbol_root(sym::prelude.clone()), edition],
|
||||
);
|
||||
|
||||
let (per_ns, _) =
|
||||
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
|
||||
let (per_ns, _) = self.def_map.resolve_path(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
DefMap::ROOT,
|
||||
&path,
|
||||
BuiltinShadowMode::Other,
|
||||
None,
|
||||
);
|
||||
|
||||
match per_ns.types {
|
||||
Some(Item { def: ModuleDefId::ModuleId(m), import, .. }) => {
|
||||
|
@ -535,6 +556,10 @@ impl DefCollector<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn local_def_map(&mut self) -> &LocalDefMap {
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map)
|
||||
}
|
||||
|
||||
/// Adds a definition of procedural macro `name` to the root module.
|
||||
///
|
||||
/// # Notes on procedural macro resolution
|
||||
|
@ -660,7 +685,13 @@ impl DefCollector<'_> {
|
|||
) {
|
||||
let vis = self
|
||||
.def_map
|
||||
.resolve_visibility(self.db, module_id, vis, false)
|
||||
.resolve_visibility(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
module_id,
|
||||
vis,
|
||||
false,
|
||||
)
|
||||
.unwrap_or(Visibility::Public);
|
||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||
self.update(
|
||||
|
@ -694,7 +725,7 @@ impl DefCollector<'_> {
|
|||
/// created by `use` in the root module, ignoring the visibility of `use`.
|
||||
fn import_macros_from_extern_crate(
|
||||
&mut self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
names: Option<Vec<Name>>,
|
||||
extern_crate: Option<ExternCrateId>,
|
||||
) {
|
||||
|
@ -779,6 +810,7 @@ impl DefCollector<'_> {
|
|||
.entered();
|
||||
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
|
||||
let res = self.def_map.resolve_path_fp_with_macro(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
ResolveMode::Import,
|
||||
module_id,
|
||||
|
@ -814,7 +846,13 @@ impl DefCollector<'_> {
|
|||
let mut def = directive.status.namespaces();
|
||||
let vis = self
|
||||
.def_map
|
||||
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
|
||||
.resolve_visibility(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
module_id,
|
||||
&directive.import.visibility,
|
||||
false,
|
||||
)
|
||||
.unwrap_or(Visibility::Public);
|
||||
|
||||
match import.source {
|
||||
|
@ -1210,6 +1248,7 @@ impl DefCollector<'_> {
|
|||
};
|
||||
let resolver = |path: &_| {
|
||||
let resolved_res = self.def_map.resolve_path_fp_with_macro(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
ResolveMode::Other,
|
||||
directive.module_id,
|
||||
|
@ -1495,7 +1534,7 @@ impl DefCollector<'_> {
|
|||
.collect(item_tree.top_level_items(), container);
|
||||
}
|
||||
|
||||
fn finish(mut self) -> DefMap {
|
||||
fn finish(mut self) -> (DefMap, LocalDefMap) {
|
||||
// Emit diagnostics for all remaining unexpanded macros.
|
||||
let _p = tracing::info_span!("DefCollector::finish").entered();
|
||||
|
||||
|
@ -1511,6 +1550,7 @@ impl DefCollector<'_> {
|
|||
self.def_map.krate,
|
||||
|path| {
|
||||
let resolved_res = self.def_map.resolve_path_fp_with_macro(
|
||||
self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
|
||||
self.db,
|
||||
ResolveMode::Other,
|
||||
directive.module_id,
|
||||
|
@ -1582,7 +1622,7 @@ impl DefCollector<'_> {
|
|||
));
|
||||
}
|
||||
|
||||
self.def_map
|
||||
(self.def_map, self.local_def_map)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1635,9 +1675,9 @@ impl ModCollector<'_, '_> {
|
|||
None,
|
||||
)
|
||||
};
|
||||
let resolve_vis = |def_map: &DefMap, visibility| {
|
||||
let resolve_vis = |def_map: &DefMap, local_def_map: &LocalDefMap, visibility| {
|
||||
def_map
|
||||
.resolve_visibility(db, module_id, visibility, false)
|
||||
.resolve_visibility(local_def_map, db, module_id, visibility, false)
|
||||
.unwrap_or(Visibility::Public)
|
||||
};
|
||||
|
||||
|
@ -1658,6 +1698,11 @@ impl ModCollector<'_, '_> {
|
|||
|
||||
let module = self.def_collector.def_map.module_id(module_id);
|
||||
let def_map = &mut self.def_collector.def_map;
|
||||
let local_def_map = self
|
||||
.def_collector
|
||||
.crate_local_def_map
|
||||
.as_deref()
|
||||
.unwrap_or(&self.def_collector.local_def_map);
|
||||
|
||||
match item {
|
||||
ModItem::Mod(m) => self.collect_module(m, &attrs),
|
||||
|
@ -1711,13 +1756,13 @@ impl ModCollector<'_, '_> {
|
|||
};
|
||||
|
||||
if let Some(resolved) = resolved {
|
||||
let vis = resolve_vis(def_map, &self.item_tree[*visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[*visibility]);
|
||||
|
||||
if is_crate_root {
|
||||
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
||||
if let Some(name) = name {
|
||||
Arc::get_mut(&mut def_map.data)
|
||||
.unwrap()
|
||||
self.def_collector
|
||||
.local_def_map
|
||||
.extern_prelude
|
||||
.insert(name.clone(), (resolved, Some(id)));
|
||||
}
|
||||
|
@ -1784,7 +1829,7 @@ impl ModCollector<'_, '_> {
|
|||
let fn_id =
|
||||
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
|
||||
if self.def_collector.def_map.block.is_none()
|
||||
&& self.def_collector.is_proc_macro
|
||||
|
@ -1804,7 +1849,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::Struct(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
StructLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1818,7 +1863,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::Union(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
UnionLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1835,7 +1880,7 @@ impl ModCollector<'_, '_> {
|
|||
EnumLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
.intern(db);
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(self.def_collector, enum_.into(), &it.name, vis, false);
|
||||
|
||||
let mut index = 0;
|
||||
|
@ -1878,7 +1923,8 @@ impl ModCollector<'_, '_> {
|
|||
|
||||
match &it.name {
|
||||
Some(name) => {
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis =
|
||||
resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(self.def_collector, const_id.into(), name, vis, false);
|
||||
}
|
||||
None => {
|
||||
|
@ -1892,7 +1938,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::Static(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
StaticLoc { container, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1906,7 +1952,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::Trait(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
TraitLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1920,7 +1966,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::TraitAlias(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
TraitAliasLoc { container: module, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1934,7 +1980,7 @@ impl ModCollector<'_, '_> {
|
|||
ModItem::TypeAlias(id) => {
|
||||
let it = &self.item_tree[id];
|
||||
|
||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||
let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
|
||||
update_def(
|
||||
self.def_collector,
|
||||
TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) }
|
||||
|
@ -1971,7 +2017,7 @@ impl ModCollector<'_, '_> {
|
|||
&mut self,
|
||||
extern_crate_id: ExternCrateId,
|
||||
macro_use_attrs: impl Iterator<Item = &'a Attr>,
|
||||
target_crate: CrateId,
|
||||
target_crate: Crate,
|
||||
) {
|
||||
cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use);
|
||||
let mut single_imports = Vec::new();
|
||||
|
@ -2115,7 +2161,16 @@ impl ModCollector<'_, '_> {
|
|||
) -> LocalModuleId {
|
||||
let def_map = &mut self.def_collector.def_map;
|
||||
let vis = def_map
|
||||
.resolve_visibility(self.def_collector.db, self.module_id, visibility, false)
|
||||
.resolve_visibility(
|
||||
self.def_collector
|
||||
.crate_local_def_map
|
||||
.as_deref()
|
||||
.unwrap_or(&self.def_collector.local_def_map),
|
||||
self.def_collector.db,
|
||||
self.module_id,
|
||||
visibility,
|
||||
false,
|
||||
)
|
||||
.unwrap_or(Visibility::Public);
|
||||
let origin = match definition {
|
||||
None => ModuleOrigin::Inline {
|
||||
|
@ -2417,6 +2472,10 @@ impl ModCollector<'_, '_> {
|
|||
},
|
||||
|path| {
|
||||
let resolved_res = self.def_collector.def_map.resolve_path_fp_with_macro(
|
||||
self.def_collector
|
||||
.crate_local_def_map
|
||||
.as_deref()
|
||||
.unwrap_or(&self.def_collector.local_def_map),
|
||||
db,
|
||||
ResolveMode::Other,
|
||||
self.module_id,
|
||||
|
@ -2517,7 +2576,6 @@ impl ModCollector<'_, '_> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::RootQueryDb;
|
||||
use test_fixture::WithFixture;
|
||||
|
||||
use crate::{nameres::DefMapCrateData, test_db::TestDB};
|
||||
|
@ -2528,6 +2586,8 @@ mod tests {
|
|||
let mut collector = DefCollector {
|
||||
db,
|
||||
def_map,
|
||||
local_def_map: LocalDefMap::default(),
|
||||
crate_local_def_map: None,
|
||||
deps: FxHashMap::default(),
|
||||
glob_imports: FxHashMap::default(),
|
||||
unresolved_imports: Vec::new(),
|
||||
|
@ -2550,7 +2610,7 @@ mod tests {
|
|||
let (db, file_id) = TestDB::with_single_file(not_ra_fixture);
|
||||
let krate = db.test_crate();
|
||||
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(&db).edition;
|
||||
let module_origin = ModuleOrigin::CrateRoot { definition: file_id };
|
||||
let def_map = DefMap::empty(
|
||||
krate,
|
||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
|||
db::DefDatabase,
|
||||
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
|
||||
item_tree::FieldsShape,
|
||||
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
||||
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs},
|
||||
path::{ModPath, PathKind},
|
||||
per_ns::PerNs,
|
||||
visibility::{RawVisibility, Visibility},
|
||||
|
@ -91,6 +91,7 @@ impl PerNs {
|
|||
impl DefMap {
|
||||
pub(crate) fn resolve_visibility(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
// module to import to
|
||||
original_module: LocalModuleId,
|
||||
|
@ -101,8 +102,14 @@ impl DefMap {
|
|||
) -> Option<Visibility> {
|
||||
let mut vis = match visibility {
|
||||
RawVisibility::Module(path, explicitness) => {
|
||||
let (result, remaining) =
|
||||
self.resolve_path(db, original_module, path, BuiltinShadowMode::Module, None);
|
||||
let (result, remaining) = self.resolve_path(
|
||||
local_def_map,
|
||||
db,
|
||||
original_module,
|
||||
path,
|
||||
BuiltinShadowMode::Module,
|
||||
None,
|
||||
);
|
||||
if remaining.is_some() {
|
||||
return None;
|
||||
}
|
||||
|
@ -137,6 +144,7 @@ impl DefMap {
|
|||
// the result.
|
||||
pub(super) fn resolve_path_fp_with_macro(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
mode: ResolveMode,
|
||||
// module to import to
|
||||
|
@ -148,6 +156,7 @@ impl DefMap {
|
|||
expected_macro_subns: Option<MacroSubNs>,
|
||||
) -> ResolvePathResult {
|
||||
let mut result = self.resolve_path_fp_with_macro_single(
|
||||
local_def_map,
|
||||
db,
|
||||
mode,
|
||||
original_module,
|
||||
|
@ -196,6 +205,7 @@ impl DefMap {
|
|||
current_map = &arc;
|
||||
|
||||
let new = current_map.resolve_path_fp_in_all_preludes(
|
||||
local_def_map,
|
||||
db,
|
||||
mode,
|
||||
original_module,
|
||||
|
@ -210,6 +220,7 @@ impl DefMap {
|
|||
}
|
||||
|
||||
let new = current_map.resolve_path_fp_with_macro_single(
|
||||
local_def_map,
|
||||
db,
|
||||
mode,
|
||||
original_module,
|
||||
|
@ -224,6 +235,7 @@ impl DefMap {
|
|||
|
||||
pub(super) fn resolve_path_fp_with_macro_single(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
mode: ResolveMode,
|
||||
original_module: LocalModuleId,
|
||||
|
@ -258,7 +270,12 @@ impl DefMap {
|
|||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||
};
|
||||
tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
|
||||
self.resolve_name_in_crate_root_or_extern_prelude(db, original_module, segment)
|
||||
self.resolve_name_in_crate_root_or_extern_prelude(
|
||||
local_def_map,
|
||||
db,
|
||||
original_module,
|
||||
segment,
|
||||
)
|
||||
}
|
||||
PathKind::Plain => {
|
||||
let (_, segment) = match segments.next() {
|
||||
|
@ -276,6 +293,7 @@ impl DefMap {
|
|||
|
||||
tracing::debug!("resolving {:?} in module", segment);
|
||||
self.resolve_name_in_module(
|
||||
local_def_map,
|
||||
db,
|
||||
original_module,
|
||||
segment,
|
||||
|
@ -321,7 +339,9 @@ impl DefMap {
|
|||
// with), resolve the remaining path segments in that `DefMap`.
|
||||
let path =
|
||||
ModPath::from_segments(PathKind::SELF, path.segments().iter().cloned());
|
||||
// This is the same crate, so the local def map is the same.
|
||||
return def_map.resolve_path_fp_with_macro(
|
||||
local_def_map,
|
||||
db,
|
||||
mode,
|
||||
local_id,
|
||||
|
@ -333,7 +353,7 @@ impl DefMap {
|
|||
|
||||
PerNs::types(module.into(), Visibility::Public, None)
|
||||
}
|
||||
PathKind::Abs => match self.resolve_path_abs(&mut segments, path) {
|
||||
PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) {
|
||||
Either::Left(it) => it,
|
||||
Either::Right(reached_fixed_point) => {
|
||||
return ResolvePathResult::empty(reached_fixed_point)
|
||||
|
@ -347,6 +367,7 @@ impl DefMap {
|
|||
/// Resolves a path only in the preludes, without accounting for item scopes.
|
||||
pub(super) fn resolve_path_fp_in_all_preludes(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
mode: ResolveMode,
|
||||
original_module: LocalModuleId,
|
||||
|
@ -368,7 +389,7 @@ impl DefMap {
|
|||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||
};
|
||||
tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
|
||||
self.resolve_name_in_extern_prelude(segment)
|
||||
self.resolve_name_in_extern_prelude(local_def_map, segment)
|
||||
}
|
||||
PathKind::Plain => {
|
||||
let (_, segment) = match segments.next() {
|
||||
|
@ -376,9 +397,9 @@ impl DefMap {
|
|||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||
};
|
||||
tracing::debug!("resolving {:?} in module", segment);
|
||||
self.resolve_name_in_all_preludes(db, segment)
|
||||
self.resolve_name_in_all_preludes(local_def_map, db, segment)
|
||||
}
|
||||
PathKind::Abs => match self.resolve_path_abs(&mut segments, path) {
|
||||
PathKind::Abs => match self.resolve_path_abs(local_def_map, &mut segments, path) {
|
||||
Either::Left(it) => it,
|
||||
Either::Right(reached_fixed_point) => {
|
||||
return ResolvePathResult::empty(reached_fixed_point)
|
||||
|
@ -395,6 +416,7 @@ impl DefMap {
|
|||
/// 2018-style absolute path -- only extern prelude
|
||||
fn resolve_path_abs<'a>(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
segments: &mut impl Iterator<Item = (usize, &'a Name)>,
|
||||
path: &ModPath,
|
||||
) -> Either<PerNs, ReachedFixedPoint> {
|
||||
|
@ -402,7 +424,7 @@ impl DefMap {
|
|||
Some((_, segment)) => segment,
|
||||
None => return Either::Right(ReachedFixedPoint::Yes),
|
||||
};
|
||||
if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
|
||||
if let Some(&(def, extern_crate)) = local_def_map.extern_prelude.get(segment) {
|
||||
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
|
||||
Either::Left(PerNs::types(
|
||||
def.into(),
|
||||
|
@ -451,6 +473,7 @@ impl DefMap {
|
|||
// this point, we know we're resolving a multi-segment path so macro kind
|
||||
// expectation is discarded.
|
||||
let resolution = defp_map.resolve_path_fp_with_macro(
|
||||
LocalDefMap::EMPTY,
|
||||
db,
|
||||
ResolveMode::Other,
|
||||
module.local_id,
|
||||
|
@ -568,6 +591,7 @@ impl DefMap {
|
|||
|
||||
fn resolve_name_in_module(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
module: LocalModuleId,
|
||||
name: &Name,
|
||||
|
@ -611,7 +635,7 @@ impl DefMap {
|
|||
// they might been shadowed by local names.
|
||||
return PerNs::none();
|
||||
}
|
||||
self.resolve_name_in_extern_prelude(name)
|
||||
self.resolve_name_in_extern_prelude(local_def_map, name)
|
||||
};
|
||||
let macro_use_prelude = || self.resolve_in_macro_use_prelude(name);
|
||||
let prelude = || {
|
||||
|
@ -628,19 +652,24 @@ impl DefMap {
|
|||
.or_else(prelude)
|
||||
}
|
||||
|
||||
fn resolve_name_in_all_preludes(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
|
||||
fn resolve_name_in_all_preludes(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
name: &Name,
|
||||
) -> PerNs {
|
||||
// Resolve in:
|
||||
// - extern prelude / macro_use prelude
|
||||
// - std prelude
|
||||
let extern_prelude = self.resolve_name_in_extern_prelude(name);
|
||||
let extern_prelude = self.resolve_name_in_extern_prelude(local_def_map, name);
|
||||
let macro_use_prelude = || self.resolve_in_macro_use_prelude(name);
|
||||
let prelude = || self.resolve_in_prelude(db, name);
|
||||
|
||||
extern_prelude.or_else(macro_use_prelude).or_else(prelude)
|
||||
}
|
||||
|
||||
fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs {
|
||||
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
|
||||
fn resolve_name_in_extern_prelude(&self, local_def_map: &LocalDefMap, name: &Name) -> PerNs {
|
||||
local_def_map.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
|
||||
PerNs::types(
|
||||
it.into(),
|
||||
Visibility::Public,
|
||||
|
@ -662,6 +691,7 @@ impl DefMap {
|
|||
|
||||
fn resolve_name_in_crate_root_or_extern_prelude(
|
||||
&self,
|
||||
local_def_map: &LocalDefMap,
|
||||
db: &dyn DefDatabase,
|
||||
module: LocalModuleId,
|
||||
name: &Name,
|
||||
|
@ -678,7 +708,7 @@ impl DefMap {
|
|||
// Don't resolve extern prelude in pseudo-module of a block.
|
||||
return PerNs::none();
|
||||
}
|
||||
self.resolve_name_in_extern_prelude(name)
|
||||
self.resolve_name_in_extern_prelude(local_def_map, name)
|
||||
};
|
||||
|
||||
from_crate_root.or_else(from_extern_prelude)
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
use base_db::SourceDatabase;
|
||||
use base_db::{
|
||||
CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData,
|
||||
DependencyBuilder, Env, RootQueryDb, SourceDatabase,
|
||||
};
|
||||
use intern::Symbol;
|
||||
use span::Edition;
|
||||
use test_fixture::WithFixture;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{db::DefDatabase, nameres::tests::TestDB, AdtId, ModuleDefId};
|
||||
|
||||
|
@ -22,6 +28,73 @@ fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change:
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crate_metadata_changes_should_not_invalidate_unrelated_def_maps() {
|
||||
let (mut db, files) = TestDB::with_many_files(
|
||||
r#"
|
||||
//- /a.rs crate:a
|
||||
pub fn foo() {}
|
||||
|
||||
//- /b.rs crate:b
|
||||
pub struct Bar;
|
||||
|
||||
//- /c.rs crate:c deps:b
|
||||
pub const BAZ: u32 = 0;
|
||||
"#,
|
||||
);
|
||||
|
||||
for &krate in db.all_crates().iter() {
|
||||
db.crate_def_map(krate);
|
||||
}
|
||||
|
||||
let all_crates_before = db.all_crates();
|
||||
|
||||
{
|
||||
// Add a dependency a -> b.
|
||||
let mut new_crate_graph = CrateGraphBuilder::default();
|
||||
let mut add_crate = |crate_name, root_file_idx: usize| {
|
||||
new_crate_graph.add_crate_root(
|
||||
files[root_file_idx].file_id(),
|
||||
Edition::CURRENT,
|
||||
Some(CrateDisplayName::from_canonical_name(crate_name)),
|
||||
None,
|
||||
Arc::default(),
|
||||
None,
|
||||
Env::default(),
|
||||
CrateOrigin::Local { repo: None, name: Some(Symbol::intern(crate_name)) },
|
||||
false,
|
||||
None,
|
||||
Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None }),
|
||||
)
|
||||
};
|
||||
let a = add_crate("a", 0);
|
||||
let b = add_crate("b", 1);
|
||||
let c = add_crate("c", 2);
|
||||
new_crate_graph
|
||||
.add_dep(c, DependencyBuilder::new(CrateName::new("b").unwrap(), b))
|
||||
.unwrap();
|
||||
new_crate_graph
|
||||
.add_dep(b, DependencyBuilder::new(CrateName::new("a").unwrap(), a))
|
||||
.unwrap();
|
||||
new_crate_graph.set_in_db(&mut db);
|
||||
}
|
||||
|
||||
let all_crates_after = db.all_crates();
|
||||
assert!(
|
||||
Arc::ptr_eq(&all_crates_before, &all_crates_after),
|
||||
"the all_crates list should not have been invalidated"
|
||||
);
|
||||
|
||||
let events = db.log_executed(|| {
|
||||
for &krate in db.all_crates().iter() {
|
||||
db.crate_def_map(krate);
|
||||
}
|
||||
});
|
||||
let invalidated_def_maps =
|
||||
events.iter().filter(|event| event.contains("crate_def_map")).count();
|
||||
assert_eq!(invalidated_def_maps, 1, "{events:#?}")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typing_inside_a_function_should_not_invalidate_def_map() {
|
||||
check_def_map_is_not_recomputed(
|
||||
|
|
|
@ -1095,7 +1095,7 @@ pub fn derive_macro_2(_item: TokenStream) -> TokenStream {
|
|||
}
|
||||
"#,
|
||||
);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
let krate = *db.all_crates().last().unwrap();
|
||||
let def_map = db.crate_def_map(krate);
|
||||
|
||||
assert_eq!(def_map.data.exported_derives.len(), 1);
|
||||
|
@ -1445,7 +1445,7 @@ struct TokenStream;
|
|||
fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a }
|
||||
"#,
|
||||
);
|
||||
let krate = db.crate_graph().iter().next().unwrap();
|
||||
let krate = *db.all_crates().last().unwrap();
|
||||
let def_map = db.crate_def_map(krate);
|
||||
|
||||
let root_module = &def_map[DefMap::ROOT].scope;
|
||||
|
|
|
@ -80,7 +80,16 @@ pub(crate) fn print_path(
|
|||
}
|
||||
PathKind::Crate => write!(buf, "crate")?,
|
||||
PathKind::Abs => {}
|
||||
PathKind::DollarCrate(_) => write!(buf, "$crate")?,
|
||||
PathKind::DollarCrate(krate) => write!(
|
||||
buf,
|
||||
"{}",
|
||||
krate
|
||||
.extra_data(db)
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map(|it| it.crate_name().symbol().as_str())
|
||||
.unwrap_or("$crate")
|
||||
)?,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Name resolution façade.
|
||||
use std::{fmt, iter, mem};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_expand::{name::Name, MacroDefId};
|
||||
use intern::{sym, Symbol};
|
||||
use itertools::Itertools as _;
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||
hir::{BindingId, ExprId, LabelId},
|
||||
item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE},
|
||||
lang_item::LangItemTarget,
|
||||
nameres::{DefMap, MacroSubNs, ResolvePathResultPrefixInfo},
|
||||
nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo},
|
||||
path::{ModPath, Path, PathKind},
|
||||
per_ns::PerNs,
|
||||
type_ref::{LifetimeRef, TypesMap},
|
||||
|
@ -47,6 +47,7 @@ pub struct Resolver {
|
|||
#[derive(Clone)]
|
||||
struct ModuleItemMap {
|
||||
def_map: Arc<DefMap>,
|
||||
local_def_map: Arc<LocalDefMap>,
|
||||
module_id: LocalModuleId,
|
||||
}
|
||||
|
||||
|
@ -278,8 +279,8 @@ impl Resolver {
|
|||
let within_impl = self.scopes().any(|scope| matches!(scope, Scope::ImplDefScope(_)));
|
||||
match visibility {
|
||||
RawVisibility::Module(_, _) => {
|
||||
let (item_map, module) = self.item_scope();
|
||||
item_map.resolve_visibility(db, module, visibility, within_impl)
|
||||
let (item_map, item_local_map, module) = self.item_scope();
|
||||
item_map.resolve_visibility(item_local_map, db, module, visibility, within_impl)
|
||||
}
|
||||
RawVisibility::Public => Some(Visibility::Public),
|
||||
}
|
||||
|
@ -474,9 +475,16 @@ impl Resolver {
|
|||
path: &ModPath,
|
||||
expected_macro_kind: Option<MacroSubNs>,
|
||||
) -> Option<(MacroId, Option<ImportOrGlob>)> {
|
||||
let (item_map, module) = self.item_scope();
|
||||
let (item_map, item_local_map, module) = self.item_scope();
|
||||
item_map
|
||||
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
|
||||
.resolve_path(
|
||||
item_local_map,
|
||||
db,
|
||||
module,
|
||||
path,
|
||||
BuiltinShadowMode::Other,
|
||||
expected_macro_kind,
|
||||
)
|
||||
.0
|
||||
.take_macros_import()
|
||||
}
|
||||
|
@ -550,7 +558,7 @@ impl Resolver {
|
|||
for scope in self.scopes() {
|
||||
scope.process_names(&mut res, db);
|
||||
}
|
||||
let ModuleItemMap { ref def_map, module_id } = self.module_scope;
|
||||
let ModuleItemMap { ref def_map, module_id, ref local_def_map } = self.module_scope;
|
||||
// FIXME: should we provide `self` here?
|
||||
// f(
|
||||
// Name::self_param(),
|
||||
|
@ -572,7 +580,7 @@ impl Resolver {
|
|||
res.add(name, ScopeDef::ModuleDef(def.into()));
|
||||
},
|
||||
);
|
||||
def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
|
||||
local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
|
||||
res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into())));
|
||||
});
|
||||
BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
|
||||
|
@ -599,7 +607,7 @@ impl Resolver {
|
|||
|
||||
pub fn extern_crates_in_scope(&self) -> impl Iterator<Item = (Name, ModuleId)> + '_ {
|
||||
self.module_scope
|
||||
.def_map
|
||||
.local_def_map
|
||||
.extern_prelude()
|
||||
.map(|(name, module_id)| (name.clone(), module_id.0.into()))
|
||||
}
|
||||
|
@ -647,11 +655,11 @@ impl Resolver {
|
|||
}
|
||||
|
||||
pub fn module(&self) -> ModuleId {
|
||||
let (def_map, local_id) = self.item_scope();
|
||||
let (def_map, _, local_id) = self.item_scope();
|
||||
def_map.module_id(local_id)
|
||||
}
|
||||
|
||||
pub fn krate(&self) -> CrateId {
|
||||
pub fn krate(&self) -> Crate {
|
||||
self.module_scope.def_map.krate()
|
||||
}
|
||||
|
||||
|
@ -844,9 +852,12 @@ impl Resolver {
|
|||
}));
|
||||
if let Some(block) = expr_scopes.block(scope_id) {
|
||||
let def_map = db.block_def_map(block);
|
||||
resolver
|
||||
.scopes
|
||||
.push(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT }));
|
||||
let local_def_map = block.lookup(db).module.only_local_def_map(db);
|
||||
resolver.scopes.push(Scope::BlockScope(ModuleItemMap {
|
||||
def_map,
|
||||
local_def_map,
|
||||
module_id: DefMap::ROOT,
|
||||
}));
|
||||
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
||||
// already traverses all parents, so this is O(n²). I think we could only store the
|
||||
// innermost module scope instead?
|
||||
|
@ -933,9 +944,10 @@ impl Resolver {
|
|||
path: &ModPath,
|
||||
shadow: BuiltinShadowMode,
|
||||
) -> PerNs {
|
||||
let (item_map, module) = self.item_scope();
|
||||
let (item_map, item_local_map, module) = self.item_scope();
|
||||
// This method resolves `path` just like import paths, so no expected macro subns is given.
|
||||
let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow, None);
|
||||
let (module_res, segment_index) =
|
||||
item_map.resolve_path(item_local_map, db, module, path, shadow, None);
|
||||
if segment_index.is_some() {
|
||||
return PerNs::none();
|
||||
}
|
||||
|
@ -943,13 +955,17 @@ impl Resolver {
|
|||
}
|
||||
|
||||
/// The innermost block scope that contains items or the module scope that contains this resolver.
|
||||
fn item_scope(&self) -> (&DefMap, LocalModuleId) {
|
||||
fn item_scope(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) {
|
||||
self.scopes()
|
||||
.find_map(|scope| match scope {
|
||||
Scope::BlockScope(m) => Some((&*m.def_map, m.module_id)),
|
||||
Scope::BlockScope(m) => Some((&*m.def_map, &*m.local_def_map, m.module_id)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or((&self.module_scope.def_map, self.module_scope.module_id))
|
||||
.unwrap_or((
|
||||
&self.module_scope.def_map,
|
||||
&self.module_scope.local_def_map,
|
||||
self.module_scope.module_id,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1066,8 @@ fn resolver_for_scope_(
|
|||
for scope in scope_chain.into_iter().rev() {
|
||||
if let Some(block) = scopes.block(scope) {
|
||||
let def_map = db.block_def_map(block);
|
||||
r = r.push_block_scope(def_map);
|
||||
let local_def_map = block.lookup(db).module.only_local_def_map(db);
|
||||
r = r.push_block_scope(def_map, local_def_map);
|
||||
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
||||
// already traverses all parents, so this is O(n²). I think we could only store the
|
||||
// innermost module scope instead?
|
||||
|
@ -1079,9 +1096,12 @@ impl Resolver {
|
|||
self.push_scope(Scope::ImplDefScope(impl_def))
|
||||
}
|
||||
|
||||
fn push_block_scope(self, def_map: Arc<DefMap>) -> Resolver {
|
||||
debug_assert!(def_map.block_id().is_some());
|
||||
self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT }))
|
||||
fn push_block_scope(self, def_map: Arc<DefMap>, local_def_map: Arc<LocalDefMap>) -> Resolver {
|
||||
self.push_scope(Scope::BlockScope(ModuleItemMap {
|
||||
def_map,
|
||||
local_def_map,
|
||||
module_id: DefMap::ROOT,
|
||||
}))
|
||||
}
|
||||
|
||||
fn push_expr_scope(
|
||||
|
@ -1100,8 +1120,13 @@ impl ModuleItemMap {
|
|||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
|
||||
let (module_def, unresolved_idx, prefix_info) =
|
||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||
let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally(
|
||||
&self.local_def_map,
|
||||
db,
|
||||
self.module_id,
|
||||
path,
|
||||
BuiltinShadowMode::Other,
|
||||
);
|
||||
match unresolved_idx {
|
||||
None => {
|
||||
let (value, import) = to_value_ns(module_def)?;
|
||||
|
@ -1134,8 +1159,13 @@ impl ModuleItemMap {
|
|||
path: &ModPath,
|
||||
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
|
||||
{
|
||||
let (module_def, idx, prefix_info) =
|
||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||
let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
|
||||
&self.local_def_map,
|
||||
db,
|
||||
self.module_id,
|
||||
path,
|
||||
BuiltinShadowMode::Other,
|
||||
);
|
||||
let (res, import) = to_type_ns(module_def)?;
|
||||
Some((res, idx, import, prefix_info))
|
||||
}
|
||||
|
@ -1230,11 +1260,14 @@ pub trait HasResolver: Copy {
|
|||
|
||||
impl HasResolver for ModuleId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
let mut def_map = self.def_map(db);
|
||||
let (mut def_map, local_def_map) = self.local_def_map(db);
|
||||
let mut module_id = self.local_id;
|
||||
|
||||
if !self.is_block_module() {
|
||||
return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, module_id } };
|
||||
return Resolver {
|
||||
scopes: vec![],
|
||||
module_scope: ModuleItemMap { def_map, local_def_map, module_id },
|
||||
};
|
||||
}
|
||||
|
||||
let mut modules: SmallVec<[_; 1]> = smallvec![];
|
||||
|
@ -1248,10 +1281,14 @@ impl HasResolver for ModuleId {
|
|||
}
|
||||
let mut resolver = Resolver {
|
||||
scopes: Vec::with_capacity(modules.len()),
|
||||
module_scope: ModuleItemMap { def_map, module_id },
|
||||
module_scope: ModuleItemMap {
|
||||
def_map,
|
||||
local_def_map: local_def_map.clone(),
|
||||
module_id,
|
||||
},
|
||||
};
|
||||
for def_map in modules.into_iter().rev() {
|
||||
resolver = resolver.push_block_scope(def_map);
|
||||
resolver = resolver.push_block_scope(def_map, local_def_map.clone());
|
||||
}
|
||||
resolver
|
||||
}
|
||||
|
@ -1259,9 +1296,10 @@ impl HasResolver for ModuleId {
|
|||
|
||||
impl HasResolver for CrateRootModuleId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
let (def_map, local_def_map) = self.local_def_map(db);
|
||||
Resolver {
|
||||
scopes: vec![],
|
||||
module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT },
|
||||
module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
|
|||
let mut map = ArenaMap::new();
|
||||
match &src.value {
|
||||
ast::StructKind::Tuple(fl) => {
|
||||
let cfg_options = &db.crate_graph()[container.krate].cfg_options;
|
||||
let cfg_options = container.krate.cfg_options(db);
|
||||
let mut idx = 0;
|
||||
for (i, fd) in fl.fields().enumerate() {
|
||||
let attrs = item_tree.attrs(
|
||||
|
@ -177,7 +177,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
|
|||
}
|
||||
}
|
||||
ast::StructKind::Record(fl) => {
|
||||
let cfg_options = &db.crate_graph()[container.krate].cfg_options;
|
||||
let cfg_options = container.krate.cfg_options(db);
|
||||
let mut idx = 0;
|
||||
for (i, fd) in fl.fields().enumerate() {
|
||||
let attrs = item_tree.attrs(
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use std::{fmt, panic, sync::Mutex};
|
||||
|
||||
use base_db::{
|
||||
CrateId, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId,
|
||||
SourceRootInput, Upcast,
|
||||
Crate, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, RootQueryDb,
|
||||
SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast,
|
||||
};
|
||||
use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile};
|
||||
use salsa::{AsDynDatabase, Durability};
|
||||
|
@ -24,6 +24,7 @@ use crate::{
|
|||
pub(crate) struct TestDB {
|
||||
storage: salsa::Storage<Self>,
|
||||
files: Arc<base_db::Files>,
|
||||
crates_map: Arc<CratesMap>,
|
||||
events: Arc<Mutex<Option<Vec<salsa::Event>>>>,
|
||||
}
|
||||
|
||||
|
@ -33,8 +34,12 @@ impl Default for TestDB {
|
|||
storage: Default::default(),
|
||||
events: Default::default(),
|
||||
files: Default::default(),
|
||||
crates_map: Default::default(),
|
||||
};
|
||||
this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
|
||||
// This needs to be here otherwise `CrateGraphBuilder` panics.
|
||||
this.set_all_crates(Arc::new(Box::new([])));
|
||||
CrateGraphBuilder::default().set_in_db(&mut this);
|
||||
this
|
||||
}
|
||||
}
|
||||
|
@ -133,20 +138,23 @@ impl SourceDatabase for TestDB {
|
|||
let files = Arc::clone(&self.files);
|
||||
files.set_file_source_root_with_durability(self, id, source_root_id, durability);
|
||||
}
|
||||
|
||||
fn crates_map(&self) -> Arc<CratesMap> {
|
||||
self.crates_map.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl TestDB {
|
||||
pub(crate) fn fetch_test_crate(&self) -> CrateId {
|
||||
let crate_graph = self.crate_graph();
|
||||
let it = crate_graph
|
||||
pub(crate) fn fetch_test_crate(&self) -> Crate {
|
||||
let all_crates = self.all_crates();
|
||||
all_crates
|
||||
.iter()
|
||||
.find(|&idx| {
|
||||
crate_graph[idx].display_name.as_ref().map(|it| it.canonical_name().as_str())
|
||||
.copied()
|
||||
.find(|&krate| {
|
||||
krate.extra_data(self).display_name.as_ref().map(|it| it.canonical_name().as_str())
|
||||
== Some("ra_test_fixture")
|
||||
})
|
||||
.or_else(|| crate_graph.iter().next())
|
||||
.unwrap();
|
||||
it
|
||||
.unwrap_or(*all_crates.last().unwrap())
|
||||
}
|
||||
|
||||
pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
||||
use std::{borrow::Cow, fmt, ops};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use cfg::CfgExpr;
|
||||
use either::Either;
|
||||
use intern::{sym, Interned, Symbol};
|
||||
|
@ -119,7 +119,7 @@ impl RawAttrs {
|
|||
|
||||
/// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
|
||||
// FIXME: This should return a different type, signaling it was filtered?
|
||||
pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs {
|
||||
pub fn filter(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs {
|
||||
let has_cfg_attrs = self
|
||||
.iter()
|
||||
.any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr.clone()));
|
||||
|
@ -127,7 +127,7 @@ impl RawAttrs {
|
|||
return self;
|
||||
}
|
||||
|
||||
let crate_graph = db.crate_graph();
|
||||
let cfg_options = krate.cfg_options(db);
|
||||
let new_attrs =
|
||||
self.iter()
|
||||
.flat_map(|attr| -> SmallVec<[_; 1]> {
|
||||
|
@ -151,7 +151,6 @@ impl RawAttrs {
|
|||
|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)),
|
||||
);
|
||||
|
||||
let cfg_options = &crate_graph[krate].cfg_options;
|
||||
let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg);
|
||||
let cfg = CfgExpr::parse(&cfg);
|
||||
if cfg_options.check(&cfg) == Some(false) {
|
||||
|
|
|
@ -231,7 +231,7 @@ fn assert_expand(
|
|||
let cond = expect_fragment(
|
||||
&mut iter,
|
||||
parser::PrefixEntryPoint::Expr,
|
||||
db.crate_graph()[id.lookup(db).krate].edition,
|
||||
id.lookup(db).krate.data(db).edition,
|
||||
tt.top_subtree().delimiter.delim_span(),
|
||||
);
|
||||
_ = iter.expect_char(',');
|
||||
|
@ -333,7 +333,7 @@ fn cfg_expand(
|
|||
) -> ExpandResult<tt::TopSubtree> {
|
||||
let loc = db.lookup_intern_macro_call(id);
|
||||
let expr = CfgExpr::parse(tt);
|
||||
let enabled = db.crate_graph()[loc.krate].cfg_options.check(&expr) != Some(false);
|
||||
let enabled = loc.krate.cfg_options(db).check(&expr) != Some(false);
|
||||
let expanded = if enabled { quote!(span=>true) } else { quote!(span=>false) };
|
||||
ExpandResult::ok(expanded)
|
||||
}
|
||||
|
@ -669,7 +669,7 @@ fn relative_file(
|
|||
if res == call_site && !allow_recursion {
|
||||
Err(ExpandError::other(err_span, format!("recursive inclusion of `{path_str}`")))
|
||||
} else {
|
||||
Ok(EditionedFileId::new(res, db.crate_graph()[lookup.krate].edition))
|
||||
Ok(EditionedFileId::new(res, lookup.krate.data(db).edition))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,7 +812,7 @@ fn include_str_expand(
|
|||
|
||||
fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &Symbol) -> Option<String> {
|
||||
let krate = db.lookup_intern_macro_call(arg_id).krate;
|
||||
db.crate_graph()[krate].env.get(key.as_str())
|
||||
krate.env(db).get(key.as_str())
|
||||
}
|
||||
|
||||
fn env_expand(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Processes out #[cfg] and #[cfg_attr] attributes from the input for the derive macro
|
||||
use std::iter::Peekable;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use cfg::{CfgAtom, CfgExpr};
|
||||
use intern::{sym, Symbol};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -13,16 +13,16 @@ use tracing::{debug, warn};
|
|||
|
||||
use crate::{db::ExpandDatabase, proc_macro::ProcMacroKind, MacroCallLoc, MacroDefKind};
|
||||
|
||||
fn check_cfg(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Option<bool> {
|
||||
fn check_cfg(db: &dyn ExpandDatabase, attr: &Attr, krate: Crate) -> Option<bool> {
|
||||
if !attr.simple_name().as_deref().map(|v| v == "cfg")? {
|
||||
return None;
|
||||
}
|
||||
let cfg = parse_from_attr_token_tree(&attr.meta()?.token_tree()?)?;
|
||||
let enabled = db.crate_graph()[krate].cfg_options.check(&cfg) != Some(false);
|
||||
let enabled = krate.cfg_options(db).check(&cfg) != Some(false);
|
||||
Some(enabled)
|
||||
}
|
||||
|
||||
fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Option<bool> {
|
||||
fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: Crate) -> Option<bool> {
|
||||
if !attr.simple_name().as_deref().map(|v| v == "cfg_attr")? {
|
||||
return None;
|
||||
}
|
||||
|
@ -32,17 +32,17 @@ fn check_cfg_attr(db: &dyn ExpandDatabase, attr: &Attr, krate: CrateId) -> Optio
|
|||
pub fn check_cfg_attr_value(
|
||||
db: &dyn ExpandDatabase,
|
||||
attr: &TokenTree,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Option<bool> {
|
||||
let cfg_expr = parse_from_attr_token_tree(attr)?;
|
||||
let enabled = db.crate_graph()[krate].cfg_options.check(&cfg_expr) != Some(false);
|
||||
let enabled = krate.cfg_options(db).check(&cfg_expr) != Some(false);
|
||||
Some(enabled)
|
||||
}
|
||||
|
||||
fn process_has_attrs_with_possible_comma<I: HasAttrs>(
|
||||
db: &dyn ExpandDatabase,
|
||||
items: impl Iterator<Item = I>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
remove: &mut FxHashSet<SyntaxElement>,
|
||||
) -> Option<()> {
|
||||
for item in items {
|
||||
|
@ -144,7 +144,7 @@ fn remove_possible_comma(item: &impl AstNode, res: &mut FxHashSet<SyntaxElement>
|
|||
fn process_enum(
|
||||
db: &dyn ExpandDatabase,
|
||||
variants: VariantList,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
remove: &mut FxHashSet<SyntaxElement>,
|
||||
) -> Option<()> {
|
||||
'variant: for variant in variants.variants() {
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
//! Defines a unit of change that can applied to the database to get the next
|
||||
//! state. Changes are transactional.
|
||||
use base_db::{CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot};
|
||||
use rustc_hash::FxHashMap;
|
||||
use base_db::{CrateGraphBuilder, FileChange, SourceRoot};
|
||||
use salsa::Durability;
|
||||
use span::FileId;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{db::ExpandDatabase, proc_macro::ProcMacros};
|
||||
use crate::{db::ExpandDatabase, proc_macro::ProcMacrosBuilder};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ChangeWithProcMacros {
|
||||
pub source_change: FileChange,
|
||||
pub proc_macros: Option<ProcMacros>,
|
||||
pub proc_macros: Option<ProcMacrosBuilder>,
|
||||
}
|
||||
|
||||
impl ChangeWithProcMacros {
|
||||
|
@ -20,8 +19,13 @@ impl ChangeWithProcMacros {
|
|||
}
|
||||
|
||||
pub fn apply(self, db: &mut impl ExpandDatabase) {
|
||||
self.source_change.apply(db);
|
||||
let crates_id_map = self.source_change.apply(db);
|
||||
if let Some(proc_macros) = self.proc_macros {
|
||||
let proc_macros = proc_macros.build(
|
||||
crates_id_map
|
||||
.as_ref()
|
||||
.expect("cannot set proc macros without setting the crate graph too"),
|
||||
);
|
||||
db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH);
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +34,11 @@ impl ChangeWithProcMacros {
|
|||
self.source_change.change_file(file_id, new_text)
|
||||
}
|
||||
|
||||
pub fn set_crate_graph(
|
||||
&mut self,
|
||||
graph: CrateGraph,
|
||||
ws_data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>,
|
||||
) {
|
||||
pub fn set_crate_graph(&mut self, graph: CrateGraphBuilder) {
|
||||
self.source_change.set_crate_graph(graph);
|
||||
self.source_change.set_ws_data(ws_data);
|
||||
}
|
||||
|
||||
pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
|
||||
pub fn set_proc_macros(&mut self, proc_macros: ProcMacrosBuilder) {
|
||||
self.proc_macros = Some(proc_macros);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Defines database & queries for macro expansion.
|
||||
|
||||
use base_db::{CrateId, RootQueryDb};
|
||||
use base_db::{Crate, RootQueryDb};
|
||||
use either::Either;
|
||||
use mbe::MatchedArmIndex;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||
span_with_call_site_ctxt, span_with_def_site_ctxt, span_with_mixed_site_ctxt,
|
||||
SyntaxContextExt as _,
|
||||
},
|
||||
proc_macro::{CustomProcMacroExpander, ProcMacros},
|
||||
proc_macro::{CrateProcMacros, CustomProcMacroExpander, ProcMacros},
|
||||
span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef},
|
||||
tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo,
|
||||
EagerExpander, ExpandError, ExpandResult, ExpandTo, MacroCallKind, MacroCallLoc, MacroDefId,
|
||||
|
@ -57,10 +57,13 @@ pub enum TokenExpander {
|
|||
|
||||
#[query_group::query_group]
|
||||
pub trait ExpandDatabase: RootQueryDb {
|
||||
/// The proc macros.
|
||||
/// The proc macros. Do not use this! Use `proc_macros_for_crate()` instead.
|
||||
#[salsa::input]
|
||||
fn proc_macros(&self) -> Arc<ProcMacros>;
|
||||
|
||||
#[salsa::invoke_actual(crate::proc_macro::proc_macros_for_crate)]
|
||||
fn proc_macros_for_crate(&self, krate: Crate) -> Option<Arc<CrateProcMacros>>;
|
||||
|
||||
fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
|
||||
|
||||
#[salsa::transparent]
|
||||
|
@ -120,7 +123,7 @@ pub trait ExpandDatabase: RootQueryDb {
|
|||
#[salsa::invoke(DeclarativeMacroExpander::expander)]
|
||||
fn decl_macro_expander(
|
||||
&self,
|
||||
def_crate: CrateId,
|
||||
def_crate: Crate,
|
||||
id: AstId<ast::Macro>,
|
||||
) -> Arc<DeclarativeMacroExpander>;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Compiled declarative macro expanders (`macro_rules!` and `macro`)
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use intern::sym;
|
||||
use span::{Edition, HirFileIdRepr, MacroCallId, Span, SyntaxContextId};
|
||||
use stdx::TupleExt;
|
||||
|
@ -70,7 +70,7 @@ impl DeclarativeMacroExpander {
|
|||
|
||||
pub(crate) fn expander(
|
||||
db: &dyn ExpandDatabase,
|
||||
def_crate: CrateId,
|
||||
def_crate: Crate,
|
||||
id: AstId<ast::Macro>,
|
||||
) -> Arc<DeclarativeMacroExpander> {
|
||||
let (root, map) = crate::db::parse_with_map(db, id.file_id);
|
||||
|
@ -101,14 +101,12 @@ impl DeclarativeMacroExpander {
|
|||
}
|
||||
};
|
||||
let ctx_edition = |ctx: SyntaxContextId| {
|
||||
let crate_graph = db.crate_graph();
|
||||
|
||||
if ctx.is_root() {
|
||||
crate_graph[def_crate].edition
|
||||
def_crate.data(db).edition
|
||||
} else {
|
||||
// UNWRAP-SAFETY: Only the root context has no outer expansion
|
||||
let krate = db.lookup_intern_macro_call(ctx.outer_expn(db).unwrap()).def.krate;
|
||||
crate_graph[krate].edition
|
||||
krate.data(db).edition
|
||||
}
|
||||
};
|
||||
let (mac, transparency) = match id.to_ptr(db).to_node(&root) {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
//!
|
||||
//!
|
||||
//! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use span::SyntaxContextId;
|
||||
use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent};
|
||||
use syntax_bridge::DocCommentDesugarMode;
|
||||
|
@ -34,7 +34,7 @@ use crate::{
|
|||
|
||||
pub fn expand_eager_macro_input(
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
macro_call: &ast::MacroCall,
|
||||
ast_id: AstId<ast::MacroCall>,
|
||||
def: MacroDefId,
|
||||
|
@ -115,7 +115,7 @@ fn lazy_expand(
|
|||
def: &MacroDefId,
|
||||
macro_call: &ast::MacroCall,
|
||||
ast_id: AstId<ast::MacroCall>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
call_site: SyntaxContextId,
|
||||
) -> ExpandResult<(InFile<Parse<SyntaxNode>>, Arc<ExpansionSpanMap>)> {
|
||||
let expand_to = ExpandTo::from_call_site(macro_call);
|
||||
|
@ -137,7 +137,7 @@ fn eager_macro_recur(
|
|||
expanded_map: &mut ExpansionSpanMap,
|
||||
mut offset: TextSize,
|
||||
curr: InFile<SyntaxNode>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
call_site: SyntaxContextId,
|
||||
macro_resolver: &dyn Fn(&ModPath) -> Option<MacroDefId>,
|
||||
) -> ExpandResult<Option<(SyntaxNode, TextSize)>> {
|
||||
|
@ -176,7 +176,7 @@ fn eager_macro_recur(
|
|||
Some(path) => match macro_resolver(&path) {
|
||||
Some(def) => def,
|
||||
None => {
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(db).edition;
|
||||
error = Some(ExpandError::other(
|
||||
span_map.span_at(call.syntax().text_range().start()),
|
||||
format!("unresolved macro {}", path.display(db, edition)),
|
||||
|
|
|
@ -33,7 +33,7 @@ use triomphe::Arc;
|
|||
use core::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use either::Either;
|
||||
use span::{
|
||||
Edition, EditionedFileId, ErasedFileAstId, FileAstId, HirFileIdRepr, Span, SpanAnchor,
|
||||
|
@ -157,7 +157,7 @@ impl ExpandError {
|
|||
pub enum ExpandErrorKind {
|
||||
/// Attribute macro expansion is disabled.
|
||||
ProcMacroAttrExpansionDisabled,
|
||||
MissingProcMacroExpander(CrateId),
|
||||
MissingProcMacroExpander(Crate),
|
||||
/// The macro for this call is disabled.
|
||||
MacroDisabled,
|
||||
/// The macro definition has errors.
|
||||
|
@ -200,7 +200,7 @@ impl ExpandErrorKind {
|
|||
kind: RenderedExpandError::DISABLED,
|
||||
},
|
||||
&ExpandErrorKind::MissingProcMacroExpander(def_crate) => {
|
||||
match db.proc_macros().get_error_for_crate(def_crate) {
|
||||
match db.proc_macros_for_crate(def_crate).as_ref().and_then(|it| it.get_error()) {
|
||||
Some((e, hard_err)) => RenderedExpandError {
|
||||
message: e.to_owned(),
|
||||
error: hard_err,
|
||||
|
@ -250,14 +250,14 @@ impl From<mbe::ExpandError> for ExpandError {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct MacroCallLoc {
|
||||
pub def: MacroDefId,
|
||||
pub krate: CrateId,
|
||||
pub krate: Crate,
|
||||
pub kind: MacroCallKind,
|
||||
pub ctxt: SyntaxContextId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MacroDefId {
|
||||
pub krate: CrateId,
|
||||
pub krate: Crate,
|
||||
pub edition: Edition,
|
||||
pub kind: MacroDefKind,
|
||||
pub local_inner: bool,
|
||||
|
@ -525,7 +525,7 @@ impl MacroDefId {
|
|||
pub fn make_call(
|
||||
self,
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
kind: MacroCallKind,
|
||||
ctxt: SyntaxContextId,
|
||||
) -> MacroCallId {
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
name::{AsName, Name},
|
||||
tt,
|
||||
};
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use intern::sym;
|
||||
use smallvec::SmallVec;
|
||||
use span::{Edition, SyntaxContextId};
|
||||
|
@ -33,7 +33,7 @@ pub enum PathKind {
|
|||
Abs,
|
||||
// FIXME: Can we remove this somehow?
|
||||
/// `$crate` from macro expansion
|
||||
DollarCrate(CrateId),
|
||||
DollarCrate(Crate),
|
||||
}
|
||||
|
||||
impl PathKind {
|
||||
|
@ -333,7 +333,7 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: tt::TokenTreesView<'_>) -> Optio
|
|||
Some(ModPath { kind, segments })
|
||||
}
|
||||
|
||||
pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option<CrateId> {
|
||||
pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> Option<Crate> {
|
||||
// When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
|
||||
// we don't want to pretend that the `macro_rules!` definition is in the `macro`
|
||||
// as described in `SyntaxContextId::apply_mark`, so we ignore prepended opaque marks.
|
||||
|
|
|
@ -260,7 +260,7 @@ impl AsName for ast::FieldKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsName for base_db::Dependency {
|
||||
impl AsName for base_db::BuiltDependency {
|
||||
fn as_name(&self) -> Name {
|
||||
Name::new_symbol_root((*self.name).clone())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Pretty printing of macros output.
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use rustc_hash::FxHashMap;
|
||||
use syntax::NodeOrToken;
|
||||
use syntax::{ast::make, SyntaxNode};
|
||||
|
@ -13,13 +13,12 @@ pub fn prettify_macro_expansion(
|
|||
db: &dyn ExpandDatabase,
|
||||
syn: SyntaxNode,
|
||||
span_map: &ExpansionSpanMap,
|
||||
target_crate_id: CrateId,
|
||||
target_crate_id: Crate,
|
||||
) -> SyntaxNode {
|
||||
// Because `syntax_bridge::prettify_macro_expansion::prettify_macro_expansion()` clones subtree for `syn`,
|
||||
// that means it will be offsetted to the beginning.
|
||||
let span_offset = syn.text_range().start();
|
||||
let crate_graph = db.crate_graph();
|
||||
let target_crate = &crate_graph[target_crate_id];
|
||||
let target_crate = target_crate_id.data(db);
|
||||
let mut syntax_ctx_id_to_dollar_crate_replacement = FxHashMap::default();
|
||||
syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(syn, &mut |dollar_crate| {
|
||||
let ctx = span_map.span_at(dollar_crate.text_range().start() + span_offset).ctx;
|
||||
|
@ -41,7 +40,7 @@ pub fn prettify_macro_expansion(
|
|||
target_crate.dependencies.iter().find(|dep| dep.crate_id == macro_def_crate)
|
||||
{
|
||||
make::tokens::ident(dep.name.as_str())
|
||||
} else if let Some(crate_name) = &crate_graph[macro_def_crate].display_name {
|
||||
} else if let Some(crate_name) = ¯o_def_crate.extra_data(db).display_name {
|
||||
make::tokens::ident(crate_name.crate_name().as_str())
|
||||
} else {
|
||||
return dollar_crate.clone();
|
||||
|
|
|
@ -1,24 +1,36 @@
|
|||
//! Proc Macro Expander stuff
|
||||
|
||||
use core::fmt;
|
||||
use std::any::Any;
|
||||
use std::{panic::RefUnwindSafe, sync};
|
||||
|
||||
use base_db::{CrateId, Env};
|
||||
use base_db::{Crate, CrateBuilderId, CratesIdMap, Env};
|
||||
use intern::Symbol;
|
||||
use rustc_hash::FxHashMap;
|
||||
use span::Span;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{db::ExpandDatabase, tt, ExpandError, ExpandErrorKind, ExpandResult};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub enum ProcMacroKind {
|
||||
CustomDerive,
|
||||
Bang,
|
||||
Attr,
|
||||
}
|
||||
|
||||
pub trait AsAny: Any {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
impl<T: Any> AsAny for T {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A proc-macro expander implementation.
|
||||
pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe {
|
||||
pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe + AsAny {
|
||||
/// Run the expander with the given input subtree, optional attribute input subtree (for
|
||||
/// [`ProcMacroKind::Attr`]), environment variables, and span information.
|
||||
fn expand(
|
||||
|
@ -31,8 +43,18 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe {
|
|||
mixed_site: Span,
|
||||
current_dir: Option<String>,
|
||||
) -> Result<tt::TopSubtree, ProcMacroExpansionError>;
|
||||
|
||||
fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool;
|
||||
}
|
||||
|
||||
impl PartialEq for dyn ProcMacroExpander {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.eq_dyn(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for dyn ProcMacroExpander {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProcMacroExpansionError {
|
||||
/// The proc-macro panicked.
|
||||
|
@ -45,41 +67,68 @@ pub type ProcMacroLoadResult = Result<Vec<ProcMacro>, (String, bool)>;
|
|||
type StoredProcMacroLoadResult = Result<Box<[ProcMacro]>, (Box<str>, bool)>;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ProcMacrosBuilder(FxHashMap<CrateId, StoredProcMacroLoadResult>);
|
||||
pub struct ProcMacrosBuilder(FxHashMap<CrateBuilderId, Arc<CrateProcMacros>>);
|
||||
|
||||
impl ProcMacrosBuilder {
|
||||
pub fn insert(&mut self, proc_macros_crate: CrateId, proc_macro: ProcMacroLoadResult) {
|
||||
pub fn insert(
|
||||
&mut self,
|
||||
proc_macros_crate: CrateBuilderId,
|
||||
mut proc_macro: ProcMacroLoadResult,
|
||||
) {
|
||||
if let Ok(proc_macros) = &mut proc_macro {
|
||||
// Sort proc macros to improve incrementality when only their order has changed (ideally the build system
|
||||
// will not change their order, but just to be sure).
|
||||
proc_macros
|
||||
.sort_unstable_by_key(|proc_macro| (proc_macro.name.clone(), proc_macro.kind));
|
||||
}
|
||||
self.0.insert(
|
||||
proc_macros_crate,
|
||||
match proc_macro {
|
||||
Ok(it) => Ok(it.into_boxed_slice()),
|
||||
Err((e, hard_err)) => Err((e.into_boxed_str(), hard_err)),
|
||||
Ok(it) => Arc::new(CrateProcMacros(Ok(it.into_boxed_slice()))),
|
||||
Err((e, hard_err)) => {
|
||||
Arc::new(CrateProcMacros(Err((e.into_boxed_str(), hard_err))))
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
pub fn build(mut self) -> ProcMacros {
|
||||
self.0.shrink_to_fit();
|
||||
ProcMacros(self.0)
|
||||
|
||||
pub(crate) fn build(self, crates_id_map: &CratesIdMap) -> ProcMacros {
|
||||
let mut map = self
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(krate, proc_macro)| (crates_id_map[&krate], proc_macro))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
map.shrink_to_fit();
|
||||
ProcMacros(map)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ProcMacros(FxHashMap<CrateId, StoredProcMacroLoadResult>);
|
||||
|
||||
impl FromIterator<(CrateId, ProcMacroLoadResult)> for ProcMacros {
|
||||
fn from_iter<T: IntoIterator<Item = (CrateId, ProcMacroLoadResult)>>(iter: T) -> Self {
|
||||
impl FromIterator<(CrateBuilderId, ProcMacroLoadResult)> for ProcMacrosBuilder {
|
||||
fn from_iter<T: IntoIterator<Item = (CrateBuilderId, ProcMacroLoadResult)>>(iter: T) -> Self {
|
||||
let mut builder = ProcMacrosBuilder::default();
|
||||
for (k, v) in iter {
|
||||
builder.insert(k, v);
|
||||
}
|
||||
builder.build()
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct CrateProcMacros(StoredProcMacroLoadResult);
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ProcMacros(FxHashMap<Crate, Arc<CrateProcMacros>>);
|
||||
impl ProcMacros {
|
||||
fn get(&self, krate: CrateId, idx: u32, err_span: Span) -> Result<&ProcMacro, ExpandError> {
|
||||
let proc_macros = match self.0.get(&krate) {
|
||||
Some(Ok(proc_macros)) => proc_macros,
|
||||
Some(Err(_)) | None => {
|
||||
fn get(&self, krate: Crate) -> Option<Arc<CrateProcMacros>> {
|
||||
self.0.get(&krate).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl CrateProcMacros {
|
||||
fn get(&self, idx: u32, err_span: Span) -> Result<&ProcMacro, ExpandError> {
|
||||
let proc_macros = match &self.0 {
|
||||
Ok(proc_macros) => proc_macros,
|
||||
Err(_) => {
|
||||
return Err(ExpandError::other(
|
||||
err_span,
|
||||
"internal error: no proc macros for crate",
|
||||
|
@ -98,18 +147,17 @@ impl ProcMacros {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn get_error_for_crate(&self, krate: CrateId) -> Option<(&str, bool)> {
|
||||
self.0.get(&krate).and_then(|it| it.as_ref().err()).map(|(e, hard_err)| (&**e, *hard_err))
|
||||
pub fn get_error(&self) -> Option<(&str, bool)> {
|
||||
self.0.as_ref().err().map(|(e, hard_err)| (&**e, *hard_err))
|
||||
}
|
||||
|
||||
/// Fetch the [`CustomProcMacroExpander`]s and their corresponding names for the given crate.
|
||||
pub fn for_crate(
|
||||
pub fn list(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
def_site_ctx: span::SyntaxContextId,
|
||||
) -> Option<Box<[(crate::name::Name, CustomProcMacroExpander, bool)]>> {
|
||||
match self.0.get(&krate) {
|
||||
Some(Ok(proc_macros)) => Some({
|
||||
match &self.0 {
|
||||
Ok(proc_macros) => Some(
|
||||
proc_macros
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
@ -117,15 +165,15 @@ impl ProcMacros {
|
|||
let name = crate::name::Name::new_symbol(it.name.clone(), def_site_ctx);
|
||||
(name, CustomProcMacroExpander::new(idx as u32), it.disabled)
|
||||
})
|
||||
.collect()
|
||||
}),
|
||||
.collect(),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A loaded proc-macro.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct ProcMacro {
|
||||
/// The name of the proc macro.
|
||||
pub name: Symbol,
|
||||
|
@ -137,6 +185,23 @@ pub struct ProcMacro {
|
|||
pub disabled: bool,
|
||||
}
|
||||
|
||||
// `#[derive(PartialEq)]` generates a strange "cannot move" error.
|
||||
impl PartialEq for ProcMacro {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let Self { name, kind, expander, disabled } = self;
|
||||
let Self {
|
||||
name: other_name,
|
||||
kind: other_kind,
|
||||
expander: other_expander,
|
||||
disabled: other_disabled,
|
||||
} = other;
|
||||
name == other_name
|
||||
&& kind == other_kind
|
||||
&& expander == other_expander
|
||||
&& disabled == other_disabled
|
||||
}
|
||||
}
|
||||
|
||||
/// A custom proc-macro expander handle. This handle together with its crate resolves to a [`ProcMacro`]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct CustomProcMacroExpander {
|
||||
|
@ -187,7 +252,7 @@ impl CustomProcMacroExpander {
|
|||
}
|
||||
|
||||
/// The macro is explicitly disabled due to proc-macro attribute expansion being disabled.
|
||||
pub fn as_expand_error(&self, def_crate: CrateId) -> Option<ExpandErrorKind> {
|
||||
pub fn as_expand_error(&self, def_crate: Crate) -> Option<ExpandErrorKind> {
|
||||
match self.proc_macro_id {
|
||||
Self::PROC_MACRO_ATTR_DISABLED => Some(ExpandErrorKind::ProcMacroAttrExpansionDisabled),
|
||||
Self::DISABLED_ID => Some(ExpandErrorKind::MacroDisabled),
|
||||
|
@ -199,8 +264,8 @@ impl CustomProcMacroExpander {
|
|||
pub fn expand(
|
||||
self,
|
||||
db: &dyn ExpandDatabase,
|
||||
def_crate: CrateId,
|
||||
calling_crate: CrateId,
|
||||
def_crate: Crate,
|
||||
calling_crate: Crate,
|
||||
tt: &tt::TopSubtree,
|
||||
attr_arg: Option<&tt::TopSubtree>,
|
||||
def_site: Span,
|
||||
|
@ -221,8 +286,22 @@ impl CustomProcMacroExpander {
|
|||
ExpandError::new(call_site, ExpandErrorKind::MacroDisabled),
|
||||
),
|
||||
id => {
|
||||
let proc_macros = db.proc_macros();
|
||||
let proc_macro = match proc_macros.get(def_crate, id, call_site) {
|
||||
let proc_macros = match db.proc_macros_for_crate(def_crate) {
|
||||
Some(it) => it,
|
||||
None => {
|
||||
return ExpandResult::new(
|
||||
tt::TopSubtree::empty(tt::DelimSpan {
|
||||
open: call_site,
|
||||
close: call_site,
|
||||
}),
|
||||
ExpandError::other(
|
||||
call_site,
|
||||
"internal error: no proc macros for crate",
|
||||
),
|
||||
)
|
||||
}
|
||||
};
|
||||
let proc_macro = match proc_macros.get(id, call_site) {
|
||||
Ok(proc_macro) => proc_macro,
|
||||
Err(e) => {
|
||||
return ExpandResult::new(
|
||||
|
@ -235,11 +314,10 @@ impl CustomProcMacroExpander {
|
|||
}
|
||||
};
|
||||
|
||||
let krate_graph = db.crate_graph();
|
||||
// Proc macros have access to the environment variables of the invoking crate.
|
||||
let env = &krate_graph[calling_crate].env;
|
||||
let env = calling_crate.env(db);
|
||||
let current_dir =
|
||||
krate_graph[calling_crate].proc_macro_cwd.as_deref().map(ToString::to_string);
|
||||
calling_crate.data(db).proc_macro_cwd.as_deref().map(ToString::to_string);
|
||||
|
||||
match proc_macro.expander.expand(
|
||||
tt,
|
||||
|
@ -278,3 +356,10 @@ impl CustomProcMacroExpander {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn proc_macros_for_crate(
|
||||
db: &dyn ExpandDatabase,
|
||||
krate: Crate,
|
||||
) -> Option<Arc<CrateProcMacros>> {
|
||||
db.proc_macros().get(krate)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use tracing::debug;
|
|||
use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds};
|
||||
use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
data::{adt::StructFlags, TraitFlags},
|
||||
hir::Movability,
|
||||
|
@ -523,7 +523,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
|
||||
impl ChalkContext<'_> {
|
||||
fn edition(&self) -> Edition {
|
||||
self.db.crate_graph()[self.krate].edition
|
||||
self.krate.data(self.db).edition
|
||||
}
|
||||
|
||||
fn for_trait_impls(
|
||||
|
@ -593,7 +593,7 @@ impl chalk_ir::UnificationDatabase<Interner> for &dyn HirDatabase {
|
|||
|
||||
pub(crate) fn program_clauses_for_chalk_env_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
environment: chalk_ir::Environment<Interner>,
|
||||
) -> chalk_ir::ProgramClauses<Interner> {
|
||||
|
@ -665,7 +665,7 @@ pub(crate) fn associated_ty_data_query(
|
|||
|
||||
pub(crate) fn trait_datum_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
trait_id: TraitId,
|
||||
) -> Arc<TraitDatum> {
|
||||
debug!("trait_datum {:?}", trait_id);
|
||||
|
@ -750,7 +750,7 @@ fn lang_item_from_well_known_trait(trait_: WellKnownTrait) -> LangItem {
|
|||
|
||||
pub(crate) fn adt_datum_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
chalk_ir::AdtId(adt_id): AdtId,
|
||||
) -> Arc<AdtDatum> {
|
||||
debug!("adt_datum {:?}", adt_id);
|
||||
|
@ -824,7 +824,7 @@ pub(crate) fn adt_datum_query(
|
|||
|
||||
pub(crate) fn impl_datum_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
impl_id: ImplId,
|
||||
) -> Arc<ImplDatum> {
|
||||
let _p = tracing::info_span!("impl_datum_query").entered();
|
||||
|
@ -833,11 +833,7 @@ pub(crate) fn impl_datum_query(
|
|||
impl_def_datum(db, krate, impl_)
|
||||
}
|
||||
|
||||
fn impl_def_datum(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
impl_id: hir_def::ImplId,
|
||||
) -> Arc<ImplDatum> {
|
||||
fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId) -> Arc<ImplDatum> {
|
||||
let trait_ref = db
|
||||
.impl_trait(impl_id)
|
||||
// ImplIds for impls where the trait ref can't be resolved should never reach Chalk
|
||||
|
@ -887,7 +883,7 @@ fn impl_def_datum(
|
|||
|
||||
pub(crate) fn associated_ty_value_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
id: AssociatedTyValueId,
|
||||
) -> Arc<AssociatedTyValue> {
|
||||
let type_alias: TypeAliasAsValue = from_chalk(db, id);
|
||||
|
@ -896,7 +892,7 @@ pub(crate) fn associated_ty_value_query(
|
|||
|
||||
fn type_alias_associated_ty_value(
|
||||
db: &dyn HirDatabase,
|
||||
_krate: CrateId,
|
||||
_krate: Crate,
|
||||
type_alias: TypeAliasId,
|
||||
) -> Arc<AssociatedTyValue> {
|
||||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Constant evaluation details
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{cast::Cast, BoundVar, DebruijnIndex};
|
||||
use hir_def::{
|
||||
expr_store::{Body, HygieneId},
|
||||
|
@ -162,7 +162,7 @@ pub fn intern_const_ref(
|
|||
db: &dyn HirDatabase,
|
||||
value: &LiteralConstRef,
|
||||
ty: Ty,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Const {
|
||||
let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate));
|
||||
let bytes = match value {
|
||||
|
@ -185,7 +185,7 @@ pub fn intern_const_ref(
|
|||
}
|
||||
|
||||
/// Interns a possibly-unknown target usize
|
||||
pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: CrateId) -> Const {
|
||||
pub fn usize_const(db: &dyn HirDatabase, value: Option<u128>, krate: Crate) -> Const {
|
||||
intern_const_ref(
|
||||
db,
|
||||
&value.map_or(LiteralConstRef::Unknown, LiteralConstRef::UInt),
|
||||
|
|
|
@ -101,10 +101,7 @@ fn check_answer(
|
|||
fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String {
|
||||
let mut err = String::new();
|
||||
let span_formatter = |file, range| format!("{file:?} {range:?}");
|
||||
let display_target = DisplayTarget::from_crate(
|
||||
&db,
|
||||
*db.crate_graph().crates_in_topological_order().last().unwrap(),
|
||||
);
|
||||
let display_target = DisplayTarget::from_crate(&db, *db.all_crates().last().unwrap());
|
||||
match e {
|
||||
ConstEvalError::MirLowerError(e) => {
|
||||
e.pretty_print(&mut err, &db, span_formatter, display_target)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::sync;
|
||||
|
||||
use base_db::{impl_intern_key, CrateId, Upcast};
|
||||
use base_db::{impl_intern_key, Crate, Upcast};
|
||||
use hir_def::{
|
||||
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
|
||||
ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
|
||||
|
@ -103,8 +103,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::cycle(crate::layout::layout_of_ty_recover)]
|
||||
fn layout_of_ty(&self, ty: Ty, env: Arc<TraitEnvironment>) -> Result<Arc<Layout>, LayoutError>;
|
||||
|
||||
#[salsa::invoke(crate::layout::target_data_layout_query)]
|
||||
fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;
|
||||
#[salsa::invoke_actual(crate::layout::target_data_layout_query)]
|
||||
fn target_data_layout(&self, krate: Crate) -> Result<Arc<TargetDataLayout>, Arc<str>>;
|
||||
|
||||
#[salsa::invoke_actual(crate::dyn_compatibility::dyn_compatibility_of_trait_query)]
|
||||
fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option<DynCompatibilityViolation>;
|
||||
|
@ -196,8 +196,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke_actual(crate::lower::generic_defaults_query)]
|
||||
fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
|
||||
|
||||
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
|
||||
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
|
||||
#[salsa::invoke_actual(InherentImpls::inherent_impls_in_crate_query)]
|
||||
fn inherent_impls_in_crate(&self, krate: Crate) -> Arc<InherentImpls>;
|
||||
|
||||
#[salsa::invoke_actual(InherentImpls::inherent_impls_in_block_query)]
|
||||
fn inherent_impls_in_block(&self, block: BlockId) -> Option<Arc<InherentImpls>>;
|
||||
|
@ -209,18 +209,18 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)]
|
||||
fn incoherent_inherent_impl_crates(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
fp: TyFingerprint,
|
||||
) -> SmallVec<[CrateId; 2]>;
|
||||
) -> SmallVec<[Crate; 2]>;
|
||||
|
||||
#[salsa::invoke(TraitImpls::trait_impls_in_crate_query)]
|
||||
fn trait_impls_in_crate(&self, krate: CrateId) -> Arc<TraitImpls>;
|
||||
#[salsa::invoke_actual(TraitImpls::trait_impls_in_crate_query)]
|
||||
fn trait_impls_in_crate(&self, krate: Crate) -> Arc<TraitImpls>;
|
||||
|
||||
#[salsa::invoke_actual(TraitImpls::trait_impls_in_block_query)]
|
||||
fn trait_impls_in_block(&self, block: BlockId) -> Option<Arc<TraitImpls>>;
|
||||
|
||||
#[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
|
||||
fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc<TraitImpls>]>;
|
||||
#[salsa::invoke_actual(TraitImpls::trait_impls_in_deps_query)]
|
||||
fn trait_impls_in_deps(&self, krate: Crate) -> Arc<[Arc<TraitImpls>]>;
|
||||
|
||||
// Interned IDs for Chalk integration
|
||||
#[salsa::interned]
|
||||
|
@ -253,23 +253,16 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke(chalk_db::trait_datum_query)]
|
||||
fn trait_datum(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
trait_id: chalk_db::TraitId,
|
||||
) -> sync::Arc<chalk_db::TraitDatum>;
|
||||
|
||||
#[salsa::invoke(chalk_db::adt_datum_query)]
|
||||
fn adt_datum(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
struct_id: chalk_db::AdtId,
|
||||
) -> sync::Arc<chalk_db::AdtDatum>;
|
||||
fn adt_datum(&self, krate: Crate, struct_id: chalk_db::AdtId) -> sync::Arc<chalk_db::AdtDatum>;
|
||||
|
||||
#[salsa::invoke(chalk_db::impl_datum_query)]
|
||||
fn impl_datum(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
impl_id: chalk_db::ImplId,
|
||||
) -> sync::Arc<chalk_db::ImplDatum>;
|
||||
fn impl_datum(&self, krate: Crate, impl_id: chalk_db::ImplId)
|
||||
-> sync::Arc<chalk_db::ImplDatum>;
|
||||
|
||||
#[salsa::invoke(chalk_db::fn_def_datum_query)]
|
||||
fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc<chalk_db::FnDefDatum>;
|
||||
|
@ -287,7 +280,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke(chalk_db::associated_ty_value_query)]
|
||||
fn associated_ty_value(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
id: chalk_db::AssociatedTyValueId,
|
||||
) -> sync::Arc<chalk_db::AssociatedTyValue>;
|
||||
|
||||
|
@ -302,7 +295,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke(crate::traits::trait_solve_query)]
|
||||
fn trait_solve(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
|
||||
) -> Option<crate::Solution>;
|
||||
|
@ -310,7 +303,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> + std::fmt::Debug {
|
|||
#[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)]
|
||||
fn program_clauses_for_chalk_env(
|
||||
&self,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
env: chalk_ir::Environment<Interner>,
|
||||
) -> chalk_ir::ProgramClauses<Interner>;
|
||||
|
|
|
@ -288,7 +288,7 @@ impl<'a> DeclValidator<'a> {
|
|||
|
||||
fn edition(&self, id: impl HasModule) -> span::Edition {
|
||||
let krate = id.krate(self.db.upcast());
|
||||
self.db.crate_graph()[krate].edition
|
||||
krate.data(self.db).edition
|
||||
}
|
||||
|
||||
fn validate_struct(&mut self, struct_id: StructId) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_solve::rust_ir::AdtKind;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
|
@ -630,7 +630,7 @@ fn missing_match_arms<'p>(
|
|||
scrut_ty: &Ty,
|
||||
witnesses: Vec<WitnessPat<'p>>,
|
||||
arms_is_empty: bool,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> String {
|
||||
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, DisplayTarget);
|
||||
impl fmt::Display for DisplayWitness<'_, '_> {
|
||||
|
|
|
@ -160,7 +160,7 @@ impl<'a> UnsafeVisitor<'a> {
|
|||
DefWithBodyId::FunctionId(func) => TargetFeatures::from_attrs(&db.attrs(func.into())),
|
||||
_ => TargetFeatures::default(),
|
||||
};
|
||||
let edition = db.crate_graph()[resolver.module().krate()].edition;
|
||||
let edition = resolver.module().krate().data(db).edition;
|
||||
Self {
|
||||
db,
|
||||
infer,
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
mem,
|
||||
};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{BoundVar, Safety, TyKind};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
|
@ -339,7 +339,7 @@ pub trait HirDisplay {
|
|||
}
|
||||
|
||||
impl HirFormatter<'_> {
|
||||
pub fn krate(&self) -> CrateId {
|
||||
pub fn krate(&self) -> Crate {
|
||||
self.display_target.krate
|
||||
}
|
||||
|
||||
|
@ -408,13 +408,13 @@ impl HirFormatter<'_> {
|
|||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DisplayTarget {
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
pub edition: Edition,
|
||||
}
|
||||
|
||||
impl DisplayTarget {
|
||||
pub fn from_crate(db: &dyn HirDatabase, krate: CrateId) -> Self {
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
pub fn from_crate(db: &dyn HirDatabase, krate: Crate) -> Self {
|
||||
let edition = krate.data(db).edition;
|
||||
Self { krate, edition }
|
||||
}
|
||||
}
|
||||
|
@ -1711,7 +1711,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
|
|||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SizedByDefault {
|
||||
NotSized,
|
||||
Sized { anchor: CrateId },
|
||||
Sized { anchor: Crate },
|
||||
}
|
||||
|
||||
impl SizedByDefault {
|
||||
|
@ -2266,8 +2266,8 @@ impl HirDisplayWithTypesMap for Path {
|
|||
// Resolve `$crate` to the crate's display name.
|
||||
// FIXME: should use the dependency name instead if available, but that depends on
|
||||
// the crate invoking `HirDisplay`
|
||||
let crate_graph = f.db.crate_graph();
|
||||
let name = crate_graph[*id]
|
||||
let crate_data = id.extra_data(f.db);
|
||||
let name = crate_data
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map(|name| name.canonical_name())
|
||||
|
|
|
@ -307,7 +307,7 @@ impl CapturedItem {
|
|||
}
|
||||
}
|
||||
}
|
||||
if is_raw_identifier(&result, db.crate_graph()[owner.module(db.upcast()).krate()].edition) {
|
||||
if is_raw_identifier(&result, owner.module(db.upcast()).krate().data(db).edition) {
|
||||
result.insert_str(0, "r#");
|
||||
}
|
||||
result
|
||||
|
@ -316,7 +316,7 @@ impl CapturedItem {
|
|||
pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
let krate = owner.krate(db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(db).edition;
|
||||
let mut result = body[self.place.local].name.display(db.upcast(), edition).to_string();
|
||||
for proj in &self.place.projections {
|
||||
match proj {
|
||||
|
@ -368,7 +368,7 @@ impl CapturedItem {
|
|||
pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
let krate = owner.krate(db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(db).edition;
|
||||
let mut result = body[self.place.local].name.display(db.upcast(), edition).to_string();
|
||||
let mut field_need_paren = false;
|
||||
for proj in &self.place.projections {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Target dependent parameters needed for layouts
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_def::layout::TargetDataLayout;
|
||||
use rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors};
|
||||
use triomphe::Arc;
|
||||
|
@ -9,9 +9,9 @@ use crate::db::HirDatabase;
|
|||
|
||||
pub fn target_data_layout_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Result<Arc<TargetDataLayout>, Arc<str>> {
|
||||
match &db.crate_workspace_data()[&krate].data_layout {
|
||||
match &krate.workspace_data(db).data_layout {
|
||||
Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) {
|
||||
Ok(it) => Ok(Arc::new(it)),
|
||||
Err(e) => {
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::{
|
|||
ops::{self, Not as _},
|
||||
};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{
|
||||
cast::Cast,
|
||||
fold::{Shift, TypeFoldable},
|
||||
|
@ -801,7 +801,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_impl_trait(&mut self, bounds: &[TypeBound], krate: CrateId) -> ImplTrait {
|
||||
fn lower_impl_trait(&mut self, bounds: &[TypeBound], krate: Crate) -> ImplTrait {
|
||||
cov_mark::hit!(lower_rpit);
|
||||
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
|
||||
let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
|
@ -1863,8 +1863,11 @@ pub(crate) fn const_or_path_to_chalk<'g>(
|
|||
.unwrap_or_else(|| unknown_const(expected_ty))
|
||||
}
|
||||
&ConstRef::Complex(it) => {
|
||||
let crate_data = &db.crate_graph()[resolver.krate()];
|
||||
if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local()
|
||||
let krate = resolver.krate();
|
||||
// Keep the `&&` this way, because it's better to access the crate data, as we access it for
|
||||
// a bunch of other things nevertheless.
|
||||
if krate.data(db).origin.is_local()
|
||||
&& krate.env(db).get("__ra_is_test_fixture").is_none()
|
||||
{
|
||||
// FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate
|
||||
// that are unlikely to be edited.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{cast::Cast, UniverseIndex, WithKind};
|
||||
use hir_def::{
|
||||
data::{adt::StructFlags, ImplData, TraitFlags},
|
||||
|
@ -148,7 +148,7 @@ pub struct TraitImpls {
|
|||
}
|
||||
|
||||
impl TraitImpls {
|
||||
pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
|
||||
pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc<Self> {
|
||||
let _p = tracing::info_span!("trait_impls_in_crate_query", ?krate).entered();
|
||||
let mut impls = FxHashMap::default();
|
||||
|
||||
|
@ -175,13 +175,11 @@ impl TraitImpls {
|
|||
|
||||
pub(crate) fn trait_impls_in_deps_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Arc<[Arc<Self>]> {
|
||||
let _p = tracing::info_span!("trait_impls_in_deps_query", ?krate).entered();
|
||||
let crate_graph = db.crate_graph();
|
||||
|
||||
Arc::from_iter(
|
||||
crate_graph.transitive_deps(krate).map(|krate| db.trait_impls_in_crate(krate)),
|
||||
db.transitive_deps(krate).into_iter().map(|krate| db.trait_impls_in_crate(krate)),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -282,7 +280,7 @@ pub struct InherentImpls {
|
|||
}
|
||||
|
||||
impl InherentImpls {
|
||||
pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
|
||||
pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: Crate) -> Arc<Self> {
|
||||
let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered();
|
||||
let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
|
||||
|
||||
|
@ -367,16 +365,15 @@ impl InherentImpls {
|
|||
|
||||
pub(crate) fn incoherent_inherent_impl_crates(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
fp: TyFingerprint,
|
||||
) -> SmallVec<[CrateId; 2]> {
|
||||
) -> SmallVec<[Crate; 2]> {
|
||||
let _p = tracing::info_span!("incoherent_inherent_impl_crates").entered();
|
||||
let mut res = SmallVec::new();
|
||||
let crate_graph = db.crate_graph();
|
||||
|
||||
// should pass crate for finger print and do reverse deps
|
||||
|
||||
for krate in crate_graph.transitive_deps(krate) {
|
||||
for krate in db.transitive_deps(krate) {
|
||||
let impls = db.inherent_impls_in_crate(krate);
|
||||
if impls.map.get(&fp).is_some_and(|v| !v.is_empty()) {
|
||||
res.push(krate);
|
||||
|
@ -386,11 +383,7 @@ pub(crate) fn incoherent_inherent_impl_crates(
|
|||
res
|
||||
}
|
||||
|
||||
pub fn def_crates(
|
||||
db: &dyn HirDatabase,
|
||||
ty: &Ty,
|
||||
cur_crate: CrateId,
|
||||
) -> Option<SmallVec<[CrateId; 2]>> {
|
||||
pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<SmallVec<[Crate; 2]>> {
|
||||
match ty.kind(Interner) {
|
||||
&TyKind::Adt(AdtId(def_id), _) => {
|
||||
let rustc_has_incoherent_inherent_impls = match def_id {
|
||||
|
@ -1226,7 +1219,7 @@ fn iterate_trait_method_candidates(
|
|||
{
|
||||
// FIXME: this should really be using the edition of the method name's span, in case it
|
||||
// comes from a macro
|
||||
if !db.crate_graph()[krate].edition.at_least_2021() {
|
||||
if !krate.data(db).edition.at_least_2021() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1239,7 +1232,7 @@ fn iterate_trait_method_candidates(
|
|||
{
|
||||
// FIXME: this should really be using the edition of the method name's span, in case it
|
||||
// comes from a macro
|
||||
if !db.crate_graph()[krate].edition.at_least_2024() {
|
||||
if !krate.data(db).edition.at_least_2024() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
|
||||
Substitution, TraitEnvironment, Ty, TyExt, TyKind,
|
||||
};
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::Mutability;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
|
@ -143,7 +143,7 @@ impl<V, T> ProjectionElem<V, T> {
|
|||
mut base: Ty,
|
||||
db: &dyn HirDatabase,
|
||||
closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> Ty {
|
||||
// we only bail on mir building when there are type mismatches
|
||||
// but error types may pop up resulting in us still attempting to build the mir
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{borrow::Cow, cell::RefCell, fmt::Write, iter, mem, ops::Range};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{cast::Cast, Mutability};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
|
@ -186,7 +186,7 @@ pub struct Evaluator<'a> {
|
|||
cached_fn_trait_func: Option<FunctionId>,
|
||||
cached_fn_mut_trait_func: Option<FunctionId>,
|
||||
cached_fn_once_trait_func: Option<FunctionId>,
|
||||
crate_id: CrateId,
|
||||
crate_id: Crate,
|
||||
// FIXME: This is a workaround, see the comment on `interpret_mir`
|
||||
assert_placeholder_ty_is_unused: bool,
|
||||
/// A general limit on execution, to prevent non terminating programs from breaking r-a main process
|
||||
|
@ -2785,7 +2785,7 @@ impl Evaluator<'_> {
|
|||
let db = self.db.upcast();
|
||||
let loc = variant.lookup(db);
|
||||
let enum_loc = loc.parent.lookup(db);
|
||||
let edition = self.db.crate_graph()[self.crate_id].edition;
|
||||
let edition = self.crate_id.data(self.db).edition;
|
||||
let name = format!(
|
||||
"{}::{}",
|
||||
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition),
|
||||
|
|
|
@ -569,7 +569,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
String::from_utf8_lossy(&name_buf)
|
||||
};
|
||||
let value = self.db.crate_graph()[self.crate_id].env.get(&name);
|
||||
let value = self.crate_id.env(self.db).get(&name);
|
||||
match value {
|
||||
None => {
|
||||
// Write null as fail
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{fmt::Write, iter, mem};
|
||||
|
||||
use base_db::{salsa::Cycle, CrateId};
|
||||
use base_db::{salsa::Cycle, Crate};
|
||||
use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
|
||||
use hir_def::{
|
||||
data::adt::{StructKind, VariantData},
|
||||
|
@ -1920,10 +1920,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
}
|
||||
|
||||
fn edition(&self) -> Edition {
|
||||
self.db.crate_graph()[self.krate()].edition
|
||||
self.krate().data(self.db).edition
|
||||
}
|
||||
|
||||
fn krate(&self) -> CrateId {
|
||||
fn krate(&self) -> Crate {
|
||||
self.owner.krate(self.db.upcast())
|
||||
}
|
||||
|
||||
|
@ -2121,7 +2121,7 @@ pub fn mir_body_for_closure_query(
|
|||
|
||||
pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<MirBody>> {
|
||||
let krate = def.krate(db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(db).edition;
|
||||
let detail = match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
db.function_data(it).name.display(db.upcast(), edition).to_string()
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use std::{fmt, panic, sync::Mutex};
|
||||
|
||||
use base_db::{
|
||||
FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId,
|
||||
SourceRootInput, Upcast,
|
||||
CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase,
|
||||
SourceRoot, SourceRootId, SourceRootInput, Upcast,
|
||||
};
|
||||
|
||||
use hir_def::{db::DefDatabase, ModuleId};
|
||||
|
@ -21,6 +21,7 @@ use triomphe::Arc;
|
|||
pub(crate) struct TestDB {
|
||||
storage: salsa::Storage<Self>,
|
||||
files: Arc<base_db::Files>,
|
||||
crates_map: Arc<CratesMap>,
|
||||
events: Arc<Mutex<Option<Vec<salsa::Event>>>>,
|
||||
}
|
||||
|
||||
|
@ -30,8 +31,12 @@ impl Default for TestDB {
|
|||
storage: Default::default(),
|
||||
events: Default::default(),
|
||||
files: Default::default(),
|
||||
crates_map: Default::default(),
|
||||
};
|
||||
this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
|
||||
// This needs to be here otherwise `CrateGraphBuilder` panics.
|
||||
this.set_all_crates(Arc::new(Box::new([])));
|
||||
CrateGraphBuilder::default().set_in_db(&mut this);
|
||||
this
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +120,10 @@ impl SourceDatabase for TestDB {
|
|||
let files = Arc::clone(&self.files);
|
||||
files.set_file_source_root_with_durability(self, id, source_root_id, durability);
|
||||
}
|
||||
|
||||
fn crates_map(&self) -> Arc<CratesMap> {
|
||||
self.crates_map.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
|
@ -151,8 +160,7 @@ impl TestDB {
|
|||
&self,
|
||||
) -> FxHashMap<EditionedFileId, Vec<(TextRange, String)>> {
|
||||
let mut files = Vec::new();
|
||||
let crate_graph = self.crate_graph();
|
||||
for krate in crate_graph.iter() {
|
||||
for &krate in self.all_crates().iter() {
|
||||
let crate_def_map = self.crate_def_map(krate);
|
||||
for (module_id, _) in crate_def_map.modules() {
|
||||
let file_id = crate_def_map[module_id].origin.file_id();
|
||||
|
|
|
@ -15,7 +15,7 @@ mod type_alias_impl_traits;
|
|||
use std::env;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use base_db::{CrateId, SourceDatabase};
|
||||
use base_db::{Crate, SourceDatabase};
|
||||
use expect_test::Expect;
|
||||
use hir_def::{
|
||||
db::DefDatabase,
|
||||
|
@ -124,7 +124,7 @@ fn check_impl(
|
|||
}
|
||||
assert!(had_annotations || allow_none, "no `//^` annotations found");
|
||||
|
||||
let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new();
|
||||
let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
|
||||
for file_id in files {
|
||||
let module = db.module_for_file_opt(file_id);
|
||||
let module = match module {
|
||||
|
@ -302,7 +302,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
let mut infer_def = |inference_result: Arc<InferenceResult>,
|
||||
body: Arc<Body>,
|
||||
body_source_map: Arc<BodySourceMap>,
|
||||
krate: CrateId| {
|
||||
krate: Crate| {
|
||||
let display_target = DisplayTarget::from_crate(&db, krate);
|
||||
let mut types: Vec<(InFile<SyntaxNode>, &Ty)> = Vec::new();
|
||||
let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
|
||||
|
@ -391,7 +391,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
let module = db.module_for_file(file_id);
|
||||
let def_map = module.def_map(&db);
|
||||
|
||||
let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new();
|
||||
let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
|
||||
visit_module(&db, &def_map, module.local_id, &mut |it| {
|
||||
let def = match it {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
|
|
|
@ -7,7 +7,7 @@ use chalk_ir::{fold::TypeFoldable, DebruijnIndex, GoalData};
|
|||
use chalk_recursive::Cache;
|
||||
use chalk_solve::{logging_db::LoggingRustIrDatabase, rust_ir, Solver};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
BlockId, TraitId,
|
||||
|
@ -30,7 +30,7 @@ const CHALK_SOLVER_FUEL: i32 = 1000;
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct ChalkContext<'a> {
|
||||
pub(crate) db: &'a dyn HirDatabase,
|
||||
pub(crate) krate: CrateId,
|
||||
pub(crate) krate: Crate,
|
||||
pub(crate) block: Option<BlockId>,
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
|
|||
/// we assume that `T: Default`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TraitEnvironment {
|
||||
pub krate: CrateId,
|
||||
pub krate: Crate,
|
||||
pub block: Option<BlockId>,
|
||||
// FIXME make this a BTreeMap
|
||||
traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
|
@ -56,7 +56,7 @@ pub struct TraitEnvironment {
|
|||
}
|
||||
|
||||
impl TraitEnvironment {
|
||||
pub fn empty(krate: CrateId) -> Arc<Self> {
|
||||
pub fn empty(krate: Crate) -> Arc<Self> {
|
||||
Arc::new(TraitEnvironment {
|
||||
krate,
|
||||
block: None,
|
||||
|
@ -66,7 +66,7 @@ impl TraitEnvironment {
|
|||
}
|
||||
|
||||
pub fn new(
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
traits_from_clauses: Box<[(Ty, TraitId)]>,
|
||||
env: chalk_ir::Environment<Interner>,
|
||||
|
@ -109,7 +109,7 @@ pub(crate) fn normalize_projection_query(
|
|||
/// Solve a trait goal using Chalk.
|
||||
pub(crate) fn trait_solve_query(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
goal: Canonical<InEnvironment<Goal>>,
|
||||
) -> Option<Solution> {
|
||||
|
@ -148,7 +148,7 @@ pub(crate) fn trait_solve_query(
|
|||
|
||||
fn solve(
|
||||
db: &dyn HirDatabase,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<Interner>>>,
|
||||
) -> Option<chalk_solve::Solution<Interner>> {
|
||||
|
@ -294,7 +294,7 @@ impl FnTrait {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_id(self, db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
|
||||
pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<TraitId> {
|
||||
let target = db.lang_item(krate, self.lang_item())?;
|
||||
match target {
|
||||
LangItemTarget::Trait(t) => Some(t),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::{hash::Hash, iter};
|
||||
|
||||
use base_db::CrateId;
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{
|
||||
fold::{FallibleTypeFolder, Shift},
|
||||
DebruijnIndex,
|
||||
|
@ -34,10 +34,7 @@ use crate::{
|
|||
TraitRefExt, Ty, WhereClause,
|
||||
};
|
||||
|
||||
pub(crate) fn fn_traits(
|
||||
db: &dyn DefDatabase,
|
||||
krate: CrateId,
|
||||
) -> impl Iterator<Item = TraitId> + '_ {
|
||||
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
|
||||
[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]
|
||||
.into_iter()
|
||||
.filter_map(move |lang| db.lang_item(krate, lang))
|
||||
|
|
|
@ -30,7 +30,7 @@ macro_rules! from_id {
|
|||
}
|
||||
|
||||
from_id![
|
||||
(base_db::CrateId, crate::Crate),
|
||||
(base_db::Crate, crate::Crate),
|
||||
(hir_def::ModuleId, crate::Module),
|
||||
(hir_def::StructId, crate::Struct),
|
||||
(hir_def::UnionId, crate::Union),
|
||||
|
|
|
@ -39,7 +39,7 @@ use std::{
|
|||
};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use base_db::{CrateDisplayName, CrateId, CrateOrigin, LangCrateOrigin};
|
||||
use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
data::{adt::VariantData, TraitFlags},
|
||||
|
@ -176,7 +176,7 @@ use {
|
|||
/// root module.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Crate {
|
||||
pub(crate) id: CrateId,
|
||||
pub(crate) id: base_db::Crate,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -187,7 +187,7 @@ pub struct CrateDependency {
|
|||
|
||||
impl Crate {
|
||||
pub fn origin(self, db: &dyn HirDatabase) -> CrateOrigin {
|
||||
db.crate_graph()[self.id].origin.clone()
|
||||
self.id.data(db).origin.clone()
|
||||
}
|
||||
|
||||
pub fn is_builtin(self, db: &dyn HirDatabase) -> bool {
|
||||
|
@ -195,7 +195,8 @@ impl Crate {
|
|||
}
|
||||
|
||||
pub fn dependencies(self, db: &dyn HirDatabase) -> Vec<CrateDependency> {
|
||||
db.crate_graph()[self.id]
|
||||
self.id
|
||||
.data(db)
|
||||
.dependencies
|
||||
.iter()
|
||||
.map(|dep| {
|
||||
|
@ -207,12 +208,11 @@ impl Crate {
|
|||
}
|
||||
|
||||
pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
|
||||
let crate_graph = db.crate_graph();
|
||||
crate_graph
|
||||
let all_crates = db.all_crates();
|
||||
all_crates
|
||||
.iter()
|
||||
.filter(|&krate| {
|
||||
crate_graph[krate].dependencies.iter().any(|it| it.crate_id == self.id)
|
||||
})
|
||||
.copied()
|
||||
.filter(|&krate| krate.data(db).dependencies.iter().any(|it| it.crate_id == self.id))
|
||||
.map(|id| Crate { id })
|
||||
.collect()
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ impl Crate {
|
|||
self,
|
||||
db: &dyn HirDatabase,
|
||||
) -> impl Iterator<Item = Crate> {
|
||||
db.crate_graph().transitive_rev_deps(self.id).map(|id| Crate { id })
|
||||
db.transitive_rev_deps(self.id).into_iter().map(|id| Crate { id })
|
||||
}
|
||||
|
||||
pub fn root_module(self) -> Module {
|
||||
|
@ -234,19 +234,19 @@ impl Crate {
|
|||
}
|
||||
|
||||
pub fn root_file(self, db: &dyn HirDatabase) -> FileId {
|
||||
db.crate_graph()[self.id].root_file_id
|
||||
self.id.data(db).root_file_id
|
||||
}
|
||||
|
||||
pub fn edition(self, db: &dyn HirDatabase) -> Edition {
|
||||
db.crate_graph()[self.id].edition
|
||||
self.id.data(db).edition
|
||||
}
|
||||
|
||||
pub fn version(self, db: &dyn HirDatabase) -> Option<String> {
|
||||
db.crate_graph()[self.id].version.clone()
|
||||
self.id.extra_data(db).version.clone()
|
||||
}
|
||||
|
||||
pub fn display_name(self, db: &dyn HirDatabase) -> Option<CrateDisplayName> {
|
||||
db.crate_graph()[self.id].display_name.clone()
|
||||
self.id.extra_data(db).display_name.clone()
|
||||
}
|
||||
|
||||
pub fn query_external_importables(
|
||||
|
@ -264,7 +264,7 @@ impl Crate {
|
|||
}
|
||||
|
||||
pub fn all(db: &dyn HirDatabase) -> Vec<Crate> {
|
||||
db.crate_graph().iter().map(|id| Crate { id }).collect()
|
||||
db.all_crates().iter().map(|&id| Crate { id }).collect()
|
||||
}
|
||||
|
||||
/// Try to get the root URL of the documentation of a crate.
|
||||
|
@ -276,12 +276,12 @@ impl Crate {
|
|||
}
|
||||
|
||||
pub fn cfg(&self, db: &dyn HirDatabase) -> Arc<CfgOptions> {
|
||||
db.crate_graph()[self.id].cfg_options.clone()
|
||||
Arc::clone(self.id.cfg_options(db))
|
||||
}
|
||||
|
||||
pub fn potential_cfg(&self, db: &dyn HirDatabase) -> Arc<CfgOptions> {
|
||||
let data = &db.crate_graph()[self.id];
|
||||
data.potential_cfg_options.clone().unwrap_or_else(|| data.cfg_options.clone())
|
||||
pub fn potential_cfg<'db>(&self, db: &'db dyn HirDatabase) -> &'db CfgOptions {
|
||||
let data = self.id.extra_data(db);
|
||||
data.potential_cfg_options.as_ref().unwrap_or_else(|| self.id.cfg_options(db))
|
||||
}
|
||||
|
||||
pub fn to_display_target(self, db: &dyn HirDatabase) -> DisplayTarget {
|
||||
|
@ -289,11 +289,12 @@ impl Crate {
|
|||
}
|
||||
|
||||
fn core(db: &dyn HirDatabase) -> Option<Crate> {
|
||||
let crate_graph = db.crate_graph();
|
||||
let result = crate_graph
|
||||
let result = db
|
||||
.all_crates()
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|&krate| {
|
||||
matches!(crate_graph[krate].origin, CrateOrigin::Lang(LangCrateOrigin::Core))
|
||||
matches!(krate.data(db).origin, CrateOrigin::Lang(LangCrateOrigin::Core))
|
||||
})
|
||||
.map(Crate::from);
|
||||
result
|
||||
|
@ -490,9 +491,7 @@ impl HasCrate for ModuleDef {
|
|||
fn krate(&self, db: &dyn HirDatabase) -> Crate {
|
||||
match self.module(db) {
|
||||
Some(module) => module.krate(),
|
||||
None => Crate::core(db).unwrap_or_else(|| {
|
||||
(*db.crate_graph().crates_in_topological_order().last().unwrap()).into()
|
||||
}),
|
||||
None => Crate::core(db).unwrap_or_else(|| db.all_crates()[0].into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -611,7 +610,7 @@ impl Module {
|
|||
style_lints: bool,
|
||||
) {
|
||||
let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered();
|
||||
let edition = db.crate_graph()[self.id.krate()].edition;
|
||||
let edition = self.id.krate().data(db).edition;
|
||||
let def_map = self.id.def_map(db.upcast());
|
||||
for diag in def_map.diagnostics() {
|
||||
if diag.in_module != self.id.local_id {
|
||||
|
@ -970,7 +969,7 @@ fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>
|
|||
return;
|
||||
};
|
||||
let krate = HasModule::krate(&m.id, db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let edition = krate.data(db).edition;
|
||||
emit_def_diagnostic_(
|
||||
db,
|
||||
acc,
|
||||
|
@ -3027,7 +3026,8 @@ impl BuiltinType {
|
|||
}
|
||||
|
||||
pub fn ty(self, db: &dyn HirDatabase) -> Type {
|
||||
Type::new_for_crate(db.crate_graph().iter().next().unwrap(), TyBuilder::builtin(self.inner))
|
||||
let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]);
|
||||
Type::new_for_crate(core, TyBuilder::builtin(self.inner))
|
||||
}
|
||||
|
||||
pub fn name(self) -> Name {
|
||||
|
@ -3968,7 +3968,7 @@ impl DeriveHelper {
|
|||
// FIXME: Wrong name? This is could also be a registered attribute
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BuiltinAttr {
|
||||
krate: Option<CrateId>,
|
||||
krate: Option<base_db::Crate>,
|
||||
idx: u32,
|
||||
}
|
||||
|
||||
|
@ -4014,7 +4014,7 @@ impl BuiltinAttr {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ToolModule {
|
||||
krate: CrateId,
|
||||
krate: base_db::Crate,
|
||||
idx: u32,
|
||||
}
|
||||
|
||||
|
@ -4732,7 +4732,7 @@ impl Type {
|
|||
Type { env: environment, ty }
|
||||
}
|
||||
|
||||
pub(crate) fn new_for_crate(krate: CrateId, ty: Ty) -> Type {
|
||||
pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty) -> Type {
|
||||
Type { env: TraitEnvironment::empty(krate), ty }
|
||||
}
|
||||
|
||||
|
@ -4794,7 +4794,7 @@ impl Type {
|
|||
Type { env: ty.env, ty: TyBuilder::slice(ty.ty) }
|
||||
}
|
||||
|
||||
pub fn new_tuple(krate: CrateId, tys: &[Type]) -> Type {
|
||||
pub fn new_tuple(krate: base_db::Crate, tys: &[Type]) -> Type {
|
||||
let tys = tys.iter().map(|it| it.ty.clone());
|
||||
Type { env: TraitEnvironment::empty(krate), ty: TyBuilder::tuple_with(tys) }
|
||||
}
|
||||
|
@ -4826,7 +4826,7 @@ impl Type {
|
|||
pub fn contains_reference(&self, db: &dyn HirDatabase) -> bool {
|
||||
return go(db, self.env.krate, &self.ty);
|
||||
|
||||
fn go(db: &dyn HirDatabase, krate: CrateId, ty: &Ty) -> bool {
|
||||
fn go(db: &dyn HirDatabase, krate: base_db::Crate, ty: &Ty) -> bool {
|
||||
match ty.kind(Interner) {
|
||||
// Reference itself
|
||||
TyKind::Ref(_, _, _) => true,
|
||||
|
@ -6209,7 +6209,7 @@ impl HasContainer for Module {
|
|||
let def_map = self.id.def_map(db.upcast());
|
||||
match def_map[self.id.local_id].parent {
|
||||
Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }),
|
||||
None => ItemContainer::Crate(def_map.krate()),
|
||||
None => ItemContainer::Crate(def_map.krate().into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6289,7 +6289,7 @@ pub enum ItemContainer {
|
|||
Impl(Impl),
|
||||
Module(Module),
|
||||
ExternBlock(ExternBlock),
|
||||
Crate(CrateId),
|
||||
Crate(Crate),
|
||||
}
|
||||
|
||||
/// Subset of `ide_db::Definition` that doc links can resolve to.
|
||||
|
|
|
@ -318,7 +318,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||
pub fn first_crate_or_default(&self, file: FileId) -> Crate {
|
||||
match self.file_to_module_defs(file).next() {
|
||||
Some(module) => module.krate(),
|
||||
None => (*self.db.crate_graph().crates_in_topological_order().last().unwrap()).into(),
|
||||
None => (*self.db.all_crates().last().unwrap()).into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,10 +77,7 @@ impl<'a> SymbolCollector<'a> {
|
|||
symbols: Default::default(),
|
||||
work: Default::default(),
|
||||
current_container_name: None,
|
||||
display_target: DisplayTarget::from_crate(
|
||||
db,
|
||||
*db.crate_graph().crates_in_topological_order().last().unwrap(),
|
||||
),
|
||||
display_target: DisplayTarget::from_crate(db, *db.all_crates().last().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use hir::{
|
|||
sym, FileRange, PathResolution, Semantics, TypeInfo,
|
||||
};
|
||||
use ide_db::{
|
||||
base_db::CrateId,
|
||||
base_db::Crate,
|
||||
defs::Definition,
|
||||
imports::insert_use::remove_path_if_in_use_stmt,
|
||||
path_transform::PathTransform,
|
||||
|
@ -251,11 +251,11 @@ struct CallInfo {
|
|||
node: ast::CallableExpr,
|
||||
arguments: Vec<ast::Expr>,
|
||||
generic_arg_list: Option<ast::GenericArgList>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
}
|
||||
|
||||
impl CallInfo {
|
||||
fn from_name_ref(name_ref: ast::NameRef, krate: CrateId) -> Option<CallInfo> {
|
||||
fn from_name_ref(name_ref: ast::NameRef, krate: Crate) -> Option<CallInfo> {
|
||||
let parent = name_ref.syntax().parent()?;
|
||||
if let Some(call) = ast::MethodCallExpr::cast(parent.clone()) {
|
||||
let receiver = call.receiver()?;
|
||||
|
|
|
@ -233,7 +233,13 @@ impl RootDatabase {
|
|||
// // SourceDatabase
|
||||
// base_db::ParseQuery
|
||||
// base_db::ParseErrorsQuery
|
||||
// base_db::CrateGraphQuery
|
||||
// base_db::AllCratesQuery
|
||||
// base_db::InternUniqueCrateDataQuery
|
||||
// base_db::InternUniqueCrateDataLookupQuery
|
||||
// base_db::CrateDataQuery
|
||||
// base_db::ExtraCrateDataQuery
|
||||
// base_db::CrateCfgQuery
|
||||
// base_db::CrateEnvQuery
|
||||
// base_db::CrateWorkspaceDataQuery
|
||||
|
||||
// // SourceDatabaseExt
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! See [`FamousDefs`].
|
||||
|
||||
use base_db::{CrateOrigin, LangCrateOrigin, RootQueryDb as _};
|
||||
use base_db::{CrateOrigin, LangCrateOrigin};
|
||||
use hir::{Crate, Enum, Function, Macro, Module, ScopeDef, Semantics, Trait};
|
||||
|
||||
use crate::RootDatabase;
|
||||
|
@ -198,11 +198,10 @@ impl FamousDefs<'_, '_> {
|
|||
fn find_lang_crate(&self, origin: LangCrateOrigin) -> Option<Crate> {
|
||||
let krate = self.1;
|
||||
let db = self.0.db;
|
||||
let crate_graph = self.0.db.crate_graph();
|
||||
let res = krate
|
||||
.dependencies(db)
|
||||
.into_iter()
|
||||
.find(|dep| crate_graph[dep.krate.into()].origin == CrateOrigin::Lang(origin))?
|
||||
.find(|dep| dep.krate.origin(db) == CrateOrigin::Lang(origin))?
|
||||
.krate;
|
||||
Some(res)
|
||||
}
|
||||
|
|
|
@ -51,9 +51,8 @@ use salsa::Durability;
|
|||
use std::{fmt, mem::ManuallyDrop};
|
||||
|
||||
use base_db::{
|
||||
query_group::{self},
|
||||
FileSourceRootInput, FileText, Files, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId,
|
||||
SourceRootInput, Upcast,
|
||||
query_group, CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, Files, RootQueryDb,
|
||||
SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, Upcast,
|
||||
};
|
||||
use hir::{
|
||||
db::{DefDatabase, ExpandDatabase, HirDatabase},
|
||||
|
@ -85,6 +84,7 @@ pub struct RootDatabase {
|
|||
// compile times of all `ide_*` and downstream crates suffer greatly.
|
||||
storage: ManuallyDrop<salsa::Storage<Self>>,
|
||||
files: Arc<Files>,
|
||||
crates_map: Arc<CratesMap>,
|
||||
}
|
||||
|
||||
impl std::panic::RefUnwindSafe for RootDatabase {}
|
||||
|
@ -102,7 +102,11 @@ impl Drop for RootDatabase {
|
|||
|
||||
impl Clone for RootDatabase {
|
||||
fn clone(&self) -> Self {
|
||||
Self { storage: self.storage.clone(), files: self.files.clone() }
|
||||
Self {
|
||||
storage: self.storage.clone(),
|
||||
files: self.files.clone(),
|
||||
crates_map: self.crates_map.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +198,10 @@ impl SourceDatabase for RootDatabase {
|
|||
let files = Arc::clone(&self.files);
|
||||
files.set_file_source_root_with_durability(self, id, source_root_id, durability);
|
||||
}
|
||||
|
||||
fn crates_map(&self) -> Arc<CratesMap> {
|
||||
self.crates_map.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RootDatabase {
|
||||
|
@ -207,8 +215,11 @@ impl RootDatabase {
|
|||
let mut db = RootDatabase {
|
||||
storage: ManuallyDrop::new(salsa::Storage::default()),
|
||||
files: Default::default(),
|
||||
crates_map: Default::default(),
|
||||
};
|
||||
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
||||
// This needs to be here otherwise `CrateGraphBuilder` will panic.
|
||||
db.set_all_crates(Arc::new(Box::new([])));
|
||||
CrateGraphBuilder::default().set_in_db(&mut db);
|
||||
db.set_proc_macros_with_durability(Default::default(), Durability::HIGH);
|
||||
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
|
||||
db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
|
||||
|
@ -258,7 +269,11 @@ impl RootDatabase {
|
|||
}
|
||||
|
||||
pub fn snapshot(&self) -> Self {
|
||||
Self { storage: self.storage.clone(), files: self.files.clone() }
|
||||
Self {
|
||||
storage: self.storage.clone(),
|
||||
files: self.files.clone(),
|
||||
crates_map: self.crates_map.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use itertools::Itertools;
|
|||
use salsa::{Cancelled, Database};
|
||||
|
||||
use crate::{
|
||||
base_db::{CrateId, RootQueryDb},
|
||||
base_db::{Crate, RootQueryDb},
|
||||
symbol_index::SymbolsDatabase,
|
||||
FxIndexMap, RootDatabase,
|
||||
};
|
||||
|
@ -35,20 +35,22 @@ pub fn parallel_prime_caches(
|
|||
) {
|
||||
let _p = tracing::info_span!("parallel_prime_caches").entered();
|
||||
|
||||
let graph = db.crate_graph();
|
||||
let mut crates_to_prime = {
|
||||
// FIXME: We already have the crate list topologically sorted (but without the things
|
||||
// `TopologicalSortIter` gives us). Maybe there is a way to avoid using it and rip it out
|
||||
// of the codebase?
|
||||
let mut builder = topologic_sort::TopologicalSortIter::builder();
|
||||
|
||||
for crate_id in graph.iter() {
|
||||
builder.add(crate_id, graph[crate_id].dependencies.iter().map(|d| d.crate_id));
|
||||
for &crate_id in db.all_crates().iter() {
|
||||
builder.add(crate_id, crate_id.data(db).dependencies.iter().map(|d| d.crate_id));
|
||||
}
|
||||
|
||||
builder.build()
|
||||
};
|
||||
|
||||
enum ParallelPrimeCacheWorkerProgress {
|
||||
BeginCrate { crate_id: CrateId, crate_name: Symbol },
|
||||
EndCrate { crate_id: CrateId },
|
||||
BeginCrate { crate_id: Crate, crate_name: Symbol },
|
||||
EndCrate { crate_id: Crate },
|
||||
}
|
||||
|
||||
// We split off def map computation from other work,
|
||||
|
@ -108,16 +110,14 @@ pub fn parallel_prime_caches(
|
|||
while crates_done < crates_total {
|
||||
db.unwind_if_revision_cancelled();
|
||||
|
||||
for crate_id in &mut crates_to_prime {
|
||||
let krate = &graph[crate_id];
|
||||
let name = krate
|
||||
.display_name
|
||||
.as_deref()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Symbol::integer(crate_id.into_raw().into_u32() as usize));
|
||||
if krate.origin.is_lang() {
|
||||
additional_phases.push((crate_id, name.clone(), PrimingPhase::ImportMap));
|
||||
} else if krate.origin.is_local() {
|
||||
for krate in &mut crates_to_prime {
|
||||
let name = krate.extra_data(db).display_name.as_deref().cloned().unwrap_or_else(|| {
|
||||
Symbol::integer(salsa::plumbing::AsId::as_id(&krate).as_u32() as usize)
|
||||
});
|
||||
let origin = &krate.data(db).origin;
|
||||
if origin.is_lang() {
|
||||
additional_phases.push((krate, name.clone(), PrimingPhase::ImportMap));
|
||||
} else if origin.is_local() {
|
||||
// Compute the symbol search index.
|
||||
// This primes the cache for `ide_db::symbol_index::world_symbols()`.
|
||||
//
|
||||
|
@ -127,10 +127,10 @@ pub fn parallel_prime_caches(
|
|||
// FIXME: We should do it unconditionally if the configuration is set to default to
|
||||
// searching dependencies (rust-analyzer.workspace.symbol.search.scope), but we
|
||||
// would need to pipe that configuration information down here.
|
||||
additional_phases.push((crate_id, name.clone(), PrimingPhase::CrateSymbols));
|
||||
additional_phases.push((krate, name.clone(), PrimingPhase::CrateSymbols));
|
||||
}
|
||||
|
||||
work_sender.send((crate_id, name, PrimingPhase::DefMap)).ok();
|
||||
work_sender.send((krate, name, PrimingPhase::DefMap)).ok();
|
||||
}
|
||||
|
||||
// recv_timeout is somewhat a hack, we need a way to from this thread check to see if the current salsa revision
|
||||
|
|
|
@ -162,13 +162,13 @@ impl SearchScope {
|
|||
fn crate_graph(db: &RootDatabase) -> SearchScope {
|
||||
let mut entries = FxHashMap::default();
|
||||
|
||||
let graph = db.crate_graph();
|
||||
for krate in graph.iter() {
|
||||
let root_file = graph[krate].root_file_id;
|
||||
let source_root = db.file_source_root(root_file).source_root_id(db);
|
||||
let all_crates = db.all_crates();
|
||||
for &krate in all_crates.iter() {
|
||||
let crate_data = krate.data(db);
|
||||
let source_root = db.file_source_root(crate_data.root_file_id).source_root_id(db);
|
||||
let source_root = db.source_root(source_root).source_root(db);
|
||||
entries.extend(
|
||||
source_root.iter().map(|id| (EditionedFileId::new(id, graph[krate].edition), None)),
|
||||
source_root.iter().map(|id| (EditionedFileId::new(id, crate_data.edition), None)),
|
||||
);
|
||||
}
|
||||
SearchScope { entries }
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(0),
|
||||
},
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(0),
|
||||
},
|
||||
|
@ -532,7 +534,9 @@
|
|||
def: Module(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(1),
|
||||
},
|
||||
|
@ -565,7 +569,9 @@
|
|||
def: Module(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(2),
|
||||
},
|
||||
|
@ -827,7 +833,9 @@
|
|||
(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(1),
|
||||
},
|
||||
|
@ -871,7 +879,9 @@
|
|||
(
|
||||
Module {
|
||||
id: ModuleId {
|
||||
krate: Idx::<CrateData>(0),
|
||||
krate: Crate {
|
||||
[salsa id]: Id(2c00),
|
||||
},
|
||||
block: None,
|
||||
local_id: Idx::<ModuleData>(2),
|
||||
},
|
||||
|
|
|
@ -389,9 +389,9 @@ pub fn semantic_diagnostics(
|
|||
module.and_then(|m| db.toolchain_channel(m.krate().into())),
|
||||
Some(ReleaseChannel::Nightly) | None
|
||||
);
|
||||
let krate = module.map(|module| module.krate()).unwrap_or_else(|| {
|
||||
(*db.crate_graph().crates_in_topological_order().last().unwrap()).into()
|
||||
});
|
||||
let krate = module
|
||||
.map(|module| module.krate())
|
||||
.unwrap_or_else(|| (*db.all_crates().last().unwrap()).into());
|
||||
let display_target = krate.to_display_target(db);
|
||||
let ctx = DiagnosticsContext { config, sema, resolve, edition, is_nightly, display_target };
|
||||
|
||||
|
|
|
@ -626,11 +626,11 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
|
|||
match_error!("Failed to get receiver type for `{}`", expr.syntax().text())
|
||||
})?
|
||||
.original;
|
||||
let krate = self.sema.scope(expr.syntax()).map(|it| it.krate()).unwrap_or_else(|| {
|
||||
hir::Crate::from(
|
||||
*self.sema.db.crate_graph().crates_in_topological_order().last().unwrap(),
|
||||
)
|
||||
});
|
||||
let krate = self
|
||||
.sema
|
||||
.scope(expr.syntax())
|
||||
.map(|it| it.krate())
|
||||
.unwrap_or_else(|| hir::Crate::from(*self.sema.db.all_crates().last().unwrap()));
|
||||
let res = code_type
|
||||
.autoderef(self.sema.db)
|
||||
.enumerate()
|
||||
|
|
|
@ -504,9 +504,7 @@ fn get_doc_base_urls(
|
|||
|
||||
let Some(krate) = krate else { return Default::default() };
|
||||
let Some(display_name) = krate.display_name(db) else { return Default::default() };
|
||||
let crate_data = &db.crate_graph()[krate.into()];
|
||||
|
||||
let (web_base, local_base) = match &crate_data.origin {
|
||||
let (web_base, local_base) = match krate.origin(db) {
|
||||
// std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself.
|
||||
// FIXME: Use the toolchains channel instead of nightly
|
||||
CrateOrigin::Lang(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use hir::db::ExpandDatabase;
|
||||
use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics};
|
||||
use ide_db::base_db::CrateId;
|
||||
use ide_db::{
|
||||
helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase,
|
||||
base_db::Crate, helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId,
|
||||
RootDatabase,
|
||||
};
|
||||
use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize};
|
||||
use stdx::format_to;
|
||||
|
@ -208,7 +208,7 @@ fn format(
|
|||
file_id: FileId,
|
||||
expanded: SyntaxNode,
|
||||
span_map: &SpanMap<SyntaxContextId>,
|
||||
krate: CrateId,
|
||||
krate: Crate,
|
||||
) -> String {
|
||||
let expansion = prettify_macro_expansion(db, expanded, span_map, krate).to_string();
|
||||
|
||||
|
@ -249,7 +249,7 @@ fn _format(
|
|||
|
||||
let upcast_db = ide_db::base_db::Upcast::<dyn ide_db::base_db::RootQueryDb>::upcast(db);
|
||||
let &crate_id = upcast_db.relevant_crates(file_id).iter().next()?;
|
||||
let edition = upcast_db.crate_graph()[crate_id].edition;
|
||||
let edition = crate_id.data(upcast_db).edition;
|
||||
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let mut cmd = std::process::Command::new(toolchain::Tool::Rustfmt.path());
|
||||
|
|
|
@ -20,21 +20,24 @@ pub struct CrateInfo {
|
|||
//
|
||||
// 
|
||||
pub(crate) fn fetch_crates(db: &RootDatabase) -> FxIndexSet<CrateInfo> {
|
||||
let crate_graph = db.crate_graph();
|
||||
crate_graph
|
||||
db.all_crates()
|
||||
.iter()
|
||||
.map(|crate_id| &crate_graph[crate_id])
|
||||
.filter(|&data| !matches!(data.origin, CrateOrigin::Local { .. }))
|
||||
.map(crate_info)
|
||||
.copied()
|
||||
.map(|crate_id| (crate_id.data(db), crate_id.extra_data(db)))
|
||||
.filter(|(data, _)| !matches!(data.origin, CrateOrigin::Local { .. }))
|
||||
.map(|(data, extra_data)| crate_info(data, extra_data))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn crate_info(data: &ide_db::base_db::CrateData) -> CrateInfo {
|
||||
let crate_name = crate_name(data);
|
||||
let version = data.version.clone();
|
||||
fn crate_info(
|
||||
data: &ide_db::base_db::BuiltCrateData,
|
||||
extra_data: &ide_db::base_db::ExtraCrateData,
|
||||
) -> CrateInfo {
|
||||
let crate_name = crate_name(extra_data);
|
||||
let version = extra_data.version.clone();
|
||||
CrateInfo { name: crate_name, version, root_file_id: data.root_file_id }
|
||||
}
|
||||
|
||||
fn crate_name(data: &ide_db::base_db::CrateData) -> Option<String> {
|
||||
fn crate_name(data: &ide_db::base_db::ExtraCrateData) -> Option<String> {
|
||||
data.display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned())
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use hir::{
|
|||
MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef,
|
||||
};
|
||||
use ide_db::{
|
||||
base_db::RootQueryDb,
|
||||
defs::Definition,
|
||||
documentation::HasDocs,
|
||||
famous_defs::FamousDefs,
|
||||
|
@ -466,8 +465,7 @@ pub(super) fn path(
|
|||
item_name: Option<String>,
|
||||
edition: Edition,
|
||||
) -> String {
|
||||
let crate_name =
|
||||
db.crate_graph()[module.krate().into()].display_name.as_ref().map(|it| it.to_string());
|
||||
let crate_name = module.krate().display_name(db).as_ref().map(|it| it.to_string());
|
||||
let module_path = module
|
||||
.path_to_root(db)
|
||||
.into_iter()
|
||||
|
|
|
@ -9252,7 +9252,7 @@ fn main() {
|
|||
S
|
||||
```
|
||||
___
|
||||
Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>"#]],
|
||||
Implements notable traits: Future<Output = u32>, Iterator<Item = S>, Notable"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -868,15 +868,15 @@ fn main() {
|
|||
//- minicore: fn
|
||||
fn main() {
|
||||
let x = || 2;
|
||||
//^ {closure#26624}
|
||||
//^ {closure#25600}
|
||||
let y = |t: i32| x() + t;
|
||||
//^ {closure#26625}
|
||||
//^ {closure#25601}
|
||||
let mut t = 5;
|
||||
//^ i32
|
||||
let z = |k: i32| { t += k; };
|
||||
//^ {closure#26626}
|
||||
//^ {closure#25602}
|
||||
let p = (y, z);
|
||||
//^ ({closure#26625}, {closure#26626})
|
||||
//^ ({closure#25601}, {closure#25602})
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
|
|
@ -57,7 +57,7 @@ mod view_memory_layout;
|
|||
mod view_mir;
|
||||
mod view_syntax_tree;
|
||||
|
||||
use std::{iter, panic::UnwindSafe};
|
||||
use std::panic::UnwindSafe;
|
||||
|
||||
use cfg::CfgOptions;
|
||||
use fetch_crates::CrateInfo;
|
||||
|
@ -125,7 +125,7 @@ pub use ide_completion::{
|
|||
};
|
||||
pub use ide_db::text_edit::{Indel, TextEdit};
|
||||
pub use ide_db::{
|
||||
base_db::{CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId},
|
||||
base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId},
|
||||
documentation::Documentation,
|
||||
label::Label,
|
||||
line_index::{LineCol, LineIndex},
|
||||
|
@ -239,7 +239,7 @@ impl Analysis {
|
|||
|
||||
let mut change = ChangeWithProcMacros::new();
|
||||
change.set_roots(vec![source_root]);
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
let mut crate_graph = CrateGraphBuilder::default();
|
||||
// FIXME: cfg options
|
||||
// Default to enable test for single file.
|
||||
let mut cfg_options = CfgOptions::default();
|
||||
|
@ -255,16 +255,13 @@ impl Analysis {
|
|||
CrateOrigin::Local { repo: None, name: None },
|
||||
false,
|
||||
None,
|
||||
);
|
||||
change.change_file(file_id, Some(text));
|
||||
let ws_data = crate_graph
|
||||
.iter()
|
||||
.zip(iter::repeat(Arc::new(CrateWorkspaceData {
|
||||
Arc::new(CrateWorkspaceData {
|
||||
data_layout: Err("fixture has no layout".into()),
|
||||
toolchain: None,
|
||||
})))
|
||||
.collect();
|
||||
change.set_crate_graph(crate_graph, ws_data);
|
||||
}),
|
||||
);
|
||||
change.change_file(file_id, Some(text));
|
||||
change.set_crate_graph(crate_graph);
|
||||
|
||||
host.apply_change(change);
|
||||
(host.analysis(), file_id)
|
||||
|
@ -372,7 +369,7 @@ impl Analysis {
|
|||
self.with_db(|db| test_explorer::discover_tests_in_crate_by_test_id(db, crate_id))
|
||||
}
|
||||
|
||||
pub fn discover_tests_in_crate(&self, crate_id: CrateId) -> Cancellable<Vec<TestItem>> {
|
||||
pub fn discover_tests_in_crate(&self, crate_id: Crate) -> Cancellable<Vec<TestItem>> {
|
||||
self.with_db(|db| test_explorer::discover_tests_in_crate(db, crate_id))
|
||||
}
|
||||
|
||||
|
@ -602,17 +599,17 @@ impl Analysis {
|
|||
}
|
||||
|
||||
/// Returns crates that this file belongs to.
|
||||
pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
|
||||
pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
|
||||
self.with_db(|db| parent_module::crates_for(db, file_id))
|
||||
}
|
||||
|
||||
/// Returns crates that this file belongs to.
|
||||
pub fn transitive_rev_deps(&self, crate_id: CrateId) -> Cancellable<Vec<CrateId>> {
|
||||
self.with_db(|db| db.crate_graph().transitive_rev_deps(crate_id).collect())
|
||||
pub fn transitive_rev_deps(&self, crate_id: Crate) -> Cancellable<Vec<Crate>> {
|
||||
self.with_db(|db| Vec::from_iter(db.transitive_rev_deps(crate_id)))
|
||||
}
|
||||
|
||||
/// Returns crates that this file *might* belong to.
|
||||
pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
|
||||
pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
|
||||
self.with_db(|db| {
|
||||
let db = Upcast::<dyn RootQueryDb>::upcast(db);
|
||||
db.relevant_crates(file_id).iter().copied().collect()
|
||||
|
@ -620,18 +617,23 @@ impl Analysis {
|
|||
}
|
||||
|
||||
/// Returns the edition of the given crate.
|
||||
pub fn crate_edition(&self, crate_id: CrateId) -> Cancellable<Edition> {
|
||||
self.with_db(|db| db.crate_graph()[crate_id].edition)
|
||||
pub fn crate_edition(&self, crate_id: Crate) -> Cancellable<Edition> {
|
||||
self.with_db(|db| crate_id.data(db).edition)
|
||||
}
|
||||
|
||||
/// Returns whether the given crate is a proc macro.
|
||||
pub fn is_proc_macro_crate(&self, crate_id: Crate) -> Cancellable<bool> {
|
||||
self.with_db(|db| crate_id.data(db).is_proc_macro)
|
||||
}
|
||||
|
||||
/// Returns true if this crate has `no_std` or `no_core` specified.
|
||||
pub fn is_crate_no_std(&self, crate_id: CrateId) -> Cancellable<bool> {
|
||||
pub fn is_crate_no_std(&self, crate_id: Crate) -> Cancellable<bool> {
|
||||
self.with_db(|db| hir::db::DefDatabase::crate_def_map(db, crate_id).is_no_std())
|
||||
}
|
||||
|
||||
/// Returns the root file of the given crate.
|
||||
pub fn crate_root(&self, crate_id: CrateId) -> Cancellable<FileId> {
|
||||
self.with_db(|db| db.crate_graph()[crate_id].root_file_id)
|
||||
pub fn crate_root(&self, crate_id: Crate) -> Cancellable<FileId> {
|
||||
self.with_db(|db| crate_id.data(db).root_file_id)
|
||||
}
|
||||
|
||||
/// Returns the set of possible targets to run for the current file.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use hir::{db::DefDatabase, Semantics};
|
||||
use ide_db::{
|
||||
base_db::{CrateId, RootQueryDb, Upcast},
|
||||
base_db::{Crate, RootQueryDb, Upcast},
|
||||
FileId, FilePosition, RootDatabase,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
@ -53,7 +53,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
|
|||
}
|
||||
|
||||
/// This returns `Vec` because a module may be included from several places.
|
||||
pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
|
||||
pub(crate) fn crates_for(db: &RootDatabase, file_id: FileId) -> Vec<Crate> {
|
||||
let root_db = Upcast::<dyn RootQueryDb>::upcast(db);
|
||||
root_db
|
||||
.relevant_crates(file_id)
|
||||
|
|
|
@ -498,9 +498,8 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> {
|
|||
};
|
||||
let krate = def.krate(db);
|
||||
let edition = krate.map(|it| it.edition(db)).unwrap_or(Edition::CURRENT);
|
||||
let display_target = krate
|
||||
.unwrap_or_else(|| (*db.crate_graph().crates_in_topological_order().last().unwrap()).into())
|
||||
.to_display_target(db);
|
||||
let display_target =
|
||||
krate.unwrap_or_else(|| (*db.all_crates().last().unwrap()).into()).to_display_target(db);
|
||||
if !has_runnable_doc_test(&attrs) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -119,9 +119,7 @@ fn documentation_for_definition(
|
|||
sema.db,
|
||||
famous_defs.as_ref(),
|
||||
def.krate(sema.db)
|
||||
.unwrap_or_else(|| {
|
||||
(*sema.db.crate_graph().crates_in_topological_order().last().unwrap()).into()
|
||||
})
|
||||
.unwrap_or_else(|| (*sema.db.all_crates().last().unwrap()).into())
|
||||
.to_display_target(sema.db),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ide_db::base_db::{CrateData, RootQueryDb, Upcast};
|
||||
use ide_db::base_db::{BuiltCrateData, ExtraCrateData};
|
||||
use ide_db::RootDatabase;
|
||||
use itertools::Itertools;
|
||||
use span::FileId;
|
||||
|
@ -34,28 +34,25 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
|
|||
if crates.is_empty() {
|
||||
format_to!(buf, "Does not belong to any crate");
|
||||
}
|
||||
|
||||
let crate_graph = Upcast::<dyn RootQueryDb>::upcast(db).crate_graph();
|
||||
for crate_id in crates {
|
||||
let CrateData {
|
||||
let BuiltCrateData {
|
||||
root_file_id,
|
||||
edition,
|
||||
version,
|
||||
display_name,
|
||||
cfg_options,
|
||||
potential_cfg_options,
|
||||
env,
|
||||
dependencies,
|
||||
origin,
|
||||
is_proc_macro,
|
||||
proc_macro_cwd,
|
||||
} = &crate_graph[crate_id];
|
||||
} = crate_id.data(db);
|
||||
let ExtraCrateData { version, display_name, potential_cfg_options } =
|
||||
crate_id.extra_data(db);
|
||||
let cfg_options = crate_id.cfg_options(db);
|
||||
let env = crate_id.env(db);
|
||||
format_to!(
|
||||
buf,
|
||||
"Crate: {}\n",
|
||||
match display_name {
|
||||
Some(it) => format!("{it}({})", crate_id.into_raw()),
|
||||
None => format!("{}", crate_id.into_raw()),
|
||||
Some(it) => format!("{it}({:?})", crate_id),
|
||||
None => format!("{:?}", crate_id),
|
||||
}
|
||||
);
|
||||
format_to!(buf, " Root module file id: {}\n", root_file_id.index());
|
||||
|
@ -69,7 +66,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
|
|||
format_to!(buf, " Proc macro cwd: {:?}\n", proc_macro_cwd);
|
||||
let deps = dependencies
|
||||
.iter()
|
||||
.map(|dep| format!("{}={}", dep.name, dep.crate_id.into_raw()))
|
||||
.map(|dep| format!("{}={:?}", dep.name, dep.crate_id))
|
||||
.format(", ");
|
||||
format_to!(buf, " Dependencies: {}\n", deps);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
//! Discovers tests
|
||||
|
||||
use hir::{Crate, Module, ModuleDef, Semantics};
|
||||
use ide_db::{
|
||||
base_db::{CrateGraph, CrateId, RootQueryDb},
|
||||
FileId, RootDatabase,
|
||||
};
|
||||
use ide_db::base_db;
|
||||
use ide_db::{base_db::RootQueryDb, FileId, RootDatabase};
|
||||
use syntax::TextRange;
|
||||
|
||||
use crate::{runnables::runnable_fn, NavigationTarget, Runnable, TryToNav};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TestItemKind {
|
||||
Crate(CrateId),
|
||||
Crate(base_db::Crate),
|
||||
Module,
|
||||
Function,
|
||||
}
|
||||
|
@ -28,12 +26,12 @@ pub struct TestItem {
|
|||
}
|
||||
|
||||
pub(crate) fn discover_test_roots(db: &RootDatabase) -> Vec<TestItem> {
|
||||
let crate_graph = db.crate_graph();
|
||||
crate_graph
|
||||
db.all_crates()
|
||||
.iter()
|
||||
.filter(|&id| crate_graph[id].origin.is_local())
|
||||
.copied()
|
||||
.filter(|&id| id.data(db).origin.is_local())
|
||||
.filter_map(|id| {
|
||||
let test_id = crate_graph[id].display_name.as_ref()?.to_string();
|
||||
let test_id = id.extra_data(db).display_name.as_ref()?.to_string();
|
||||
Some(TestItem {
|
||||
kind: TestItemKind::Crate(id),
|
||||
label: test_id.clone(),
|
||||
|
@ -47,12 +45,12 @@ pub(crate) fn discover_test_roots(db: &RootDatabase) -> Vec<TestItem> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn find_crate_by_id(crate_graph: &CrateGraph, crate_id: &str) -> Option<CrateId> {
|
||||
fn find_crate_by_id(db: &RootDatabase, crate_id: &str) -> Option<base_db::Crate> {
|
||||
// here, we use display_name as the crate id. This is not super ideal, but it works since we
|
||||
// only show tests for the local crates.
|
||||
crate_graph.iter().find(|&id| {
|
||||
crate_graph[id].origin.is_local()
|
||||
&& crate_graph[id].display_name.as_ref().is_some_and(|x| x.to_string() == crate_id)
|
||||
db.all_crates().iter().copied().find(|&id| {
|
||||
id.data(db).origin.is_local()
|
||||
&& id.extra_data(db).display_name.as_ref().is_some_and(|x| x.to_string() == crate_id)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -115,8 +113,7 @@ pub(crate) fn discover_tests_in_crate_by_test_id(
|
|||
db: &RootDatabase,
|
||||
crate_test_id: &str,
|
||||
) -> Vec<TestItem> {
|
||||
let crate_graph = db.crate_graph();
|
||||
let Some(crate_id) = find_crate_by_id(&crate_graph, crate_test_id) else {
|
||||
let Some(crate_id) = find_crate_by_id(db, crate_test_id) else {
|
||||
return vec![];
|
||||
};
|
||||
discover_tests_in_crate(db, crate_id)
|
||||
|
@ -171,12 +168,14 @@ fn find_module_id_and_test_parents(
|
|||
Some((r, id))
|
||||
}
|
||||
|
||||
pub(crate) fn discover_tests_in_crate(db: &RootDatabase, crate_id: CrateId) -> Vec<TestItem> {
|
||||
let crate_graph = db.crate_graph();
|
||||
if !crate_graph[crate_id].origin.is_local() {
|
||||
pub(crate) fn discover_tests_in_crate(
|
||||
db: &RootDatabase,
|
||||
crate_id: base_db::Crate,
|
||||
) -> Vec<TestItem> {
|
||||
if !crate_id.data(db).origin.is_local() {
|
||||
return vec![];
|
||||
}
|
||||
let Some(crate_test_id) = &crate_graph[crate_id].display_name else {
|
||||
let Some(crate_test_id) = &crate_id.extra_data(db).display_name else {
|
||||
return vec![];
|
||||
};
|
||||
let kind = TestItemKind::Crate(crate_id);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use dot::{Id, LabelText};
|
||||
use ide_db::{
|
||||
base_db::{CrateGraph, CrateId, Dependency, RootQueryDb, SourceDatabase, Upcast},
|
||||
FxHashSet, RootDatabase,
|
||||
base_db::{
|
||||
BuiltCrateData, BuiltDependency, Crate, ExtraCrateData, RootQueryDb, SourceDatabase,
|
||||
},
|
||||
FxHashMap, RootDatabase,
|
||||
};
|
||||
use triomphe::Arc;
|
||||
|
||||
// Feature: View Crate Graph
|
||||
//
|
||||
|
@ -16,77 +17,80 @@ use triomphe::Arc;
|
|||
// |---------|-------------|
|
||||
// | VS Code | **rust-analyzer: View Crate Graph** |
|
||||
pub(crate) fn view_crate_graph(db: &RootDatabase, full: bool) -> Result<String, String> {
|
||||
let crate_graph = Upcast::<dyn RootQueryDb>::upcast(db).crate_graph();
|
||||
let crates_to_render = crate_graph
|
||||
let all_crates = db.all_crates();
|
||||
let crates_to_render = all_crates
|
||||
.iter()
|
||||
.filter(|krate| {
|
||||
.copied()
|
||||
.map(|krate| (krate, (krate.data(db), krate.extra_data(db))))
|
||||
.filter(|(_, (crate_data, _))| {
|
||||
if full {
|
||||
true
|
||||
} else {
|
||||
// Only render workspace crates
|
||||
let root_id =
|
||||
db.file_source_root(crate_graph[*krate].root_file_id).source_root_id(db);
|
||||
let root_id = db.file_source_root(crate_data.root_file_id).source_root_id(db);
|
||||
!db.source_root(root_id).source_root(db).is_library
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let graph = DotCrateGraph { graph: crate_graph, crates_to_render };
|
||||
let graph = DotCrateGraph { crates_to_render };
|
||||
|
||||
let mut dot = Vec::new();
|
||||
dot::render(&graph, &mut dot).unwrap();
|
||||
Ok(String::from_utf8(dot).unwrap())
|
||||
}
|
||||
|
||||
struct DotCrateGraph {
|
||||
graph: Arc<CrateGraph>,
|
||||
crates_to_render: FxHashSet<CrateId>,
|
||||
struct DotCrateGraph<'db> {
|
||||
crates_to_render: FxHashMap<Crate, (&'db BuiltCrateData, &'db ExtraCrateData)>,
|
||||
}
|
||||
|
||||
type Edge<'a> = (CrateId, &'a Dependency);
|
||||
type Edge<'a> = (Crate, &'a BuiltDependency);
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, CrateId, Edge<'a>> for DotCrateGraph {
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, CrateId> {
|
||||
self.crates_to_render.iter().copied().collect()
|
||||
impl<'a> dot::GraphWalk<'a, Crate, Edge<'a>> for DotCrateGraph<'_> {
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Crate> {
|
||||
self.crates_to_render.keys().copied().collect()
|
||||
}
|
||||
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> {
|
||||
self.crates_to_render
|
||||
.iter()
|
||||
.flat_map(|krate| {
|
||||
self.graph[*krate]
|
||||
.flat_map(|(krate, (crate_data, _))| {
|
||||
crate_data
|
||||
.dependencies
|
||||
.iter()
|
||||
.filter(|dep| self.crates_to_render.contains(&dep.crate_id))
|
||||
.filter(|dep| self.crates_to_render.contains_key(&dep.crate_id))
|
||||
.map(move |dep| (*krate, dep))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn source(&'a self, edge: &Edge<'a>) -> CrateId {
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Crate {
|
||||
edge.0
|
||||
}
|
||||
|
||||
fn target(&'a self, edge: &Edge<'a>) -> CrateId {
|
||||
fn target(&'a self, edge: &Edge<'a>) -> Crate {
|
||||
edge.1.crate_id
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::Labeller<'a, CrateId, Edge<'a>> for DotCrateGraph {
|
||||
impl<'a> dot::Labeller<'a, Crate, Edge<'a>> for DotCrateGraph<'_> {
|
||||
fn graph_id(&'a self) -> Id<'a> {
|
||||
Id::new("rust_analyzer_crate_graph").unwrap()
|
||||
}
|
||||
|
||||
fn node_id(&'a self, n: &CrateId) -> Id<'a> {
|
||||
Id::new(format!("_{}", u32::from(n.into_raw()))).unwrap()
|
||||
fn node_id(&'a self, n: &Crate) -> Id<'a> {
|
||||
Id::new(format!("_{:?}", n)).unwrap()
|
||||
}
|
||||
|
||||
fn node_shape(&'a self, _node: &CrateId) -> Option<LabelText<'a>> {
|
||||
fn node_shape(&'a self, _node: &Crate) -> Option<LabelText<'a>> {
|
||||
Some(LabelText::LabelStr("box".into()))
|
||||
}
|
||||
|
||||
fn node_label(&'a self, n: &CrateId) -> LabelText<'a> {
|
||||
let name =
|
||||
self.graph[*n].display_name.as_ref().map_or("(unnamed crate)", |name| name.as_str());
|
||||
fn node_label(&'a self, n: &Crate) -> LabelText<'a> {
|
||||
let name = self.crates_to_render[n]
|
||||
.1
|
||||
.display_name
|
||||
.as_ref()
|
||||
.map_or("(unnamed crate)", |name| name.as_str());
|
||||
LabelText::LabelStr(name.into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,18 @@ struct TaggedArcPtr {
|
|||
unsafe impl Send for TaggedArcPtr {}
|
||||
unsafe impl Sync for TaggedArcPtr {}
|
||||
|
||||
impl Ord for TaggedArcPtr {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.as_str().cmp(other.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for TaggedArcPtr {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl TaggedArcPtr {
|
||||
const BOOL_BITS: usize = true as usize;
|
||||
|
||||
|
@ -113,7 +125,7 @@ impl TaggedArcPtr {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Symbol {
|
||||
repr: TaggedArcPtr,
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
//! for incorporating changes.
|
||||
// Note, don't remove any public api from this. This API is consumed by external tools
|
||||
// to run rust-analyzer as a library.
|
||||
use std::{collections::hash_map::Entry, iter, mem, path::Path, sync};
|
||||
use std::{collections::hash_map::Entry, mem, path::Path, sync};
|
||||
|
||||
use crossbeam_channel::{unbounded, Receiver};
|
||||
use hir_expand::proc_macro::{
|
||||
ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult,
|
||||
ProcMacros,
|
||||
ProcMacrosBuilder,
|
||||
};
|
||||
use ide_db::{
|
||||
base_db::{CrateGraph, CrateWorkspaceData, Env, SourceRoot, SourceRootId},
|
||||
base_db::{CrateGraphBuilder, Env, SourceRoot, SourceRootId},
|
||||
prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
@ -139,7 +139,6 @@ pub fn load_workspace(
|
|||
});
|
||||
|
||||
let db = load_crate_graph(
|
||||
&ws,
|
||||
crate_graph,
|
||||
proc_macros,
|
||||
project_folders.source_root_config,
|
||||
|
@ -418,15 +417,12 @@ pub fn load_proc_macro(
|
|||
}
|
||||
|
||||
fn load_crate_graph(
|
||||
ws: &ProjectWorkspace,
|
||||
crate_graph: CrateGraph,
|
||||
proc_macros: ProcMacros,
|
||||
crate_graph: CrateGraphBuilder,
|
||||
proc_macros: ProcMacrosBuilder,
|
||||
source_root_config: SourceRootConfig,
|
||||
vfs: &mut vfs::Vfs,
|
||||
receiver: &Receiver<vfs::loader::Message>,
|
||||
) -> RootDatabase {
|
||||
let ProjectWorkspace { toolchain, target_layout, .. } = ws;
|
||||
|
||||
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<u16>().ok());
|
||||
let mut db = RootDatabase::new(lru_cap);
|
||||
let mut analysis_change = ChangeWithProcMacros::new();
|
||||
|
@ -461,14 +457,7 @@ fn load_crate_graph(
|
|||
let source_roots = source_root_config.partition(vfs);
|
||||
analysis_change.set_roots(source_roots);
|
||||
|
||||
let ws_data = crate_graph
|
||||
.iter()
|
||||
.zip(iter::repeat(From::from(CrateWorkspaceData {
|
||||
data_layout: target_layout.clone(),
|
||||
toolchain: toolchain.clone(),
|
||||
})))
|
||||
.collect();
|
||||
analysis_change.set_crate_graph(crate_graph, ws_data);
|
||||
analysis_change.set_crate_graph(crate_graph);
|
||||
analysis_change.set_proc_macros(proc_macros);
|
||||
|
||||
db.apply_change(analysis_change);
|
||||
|
@ -494,7 +483,7 @@ fn expander_to_proc_macro(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct Expander(proc_macro_api::ProcMacro);
|
||||
|
||||
impl ProcMacroExpander for Expander {
|
||||
|
@ -522,6 +511,10 @@ impl ProcMacroExpander for Expander {
|
|||
Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().is_some_and(|other| self == other)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -543,7 +536,7 @@ mod tests {
|
|||
let (db, _vfs, _proc_macro) =
|
||||
load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap();
|
||||
|
||||
let n_crates = db.crate_graph().iter().count();
|
||||
let n_crates = db.all_crates().len();
|
||||
// RA has quite a few crates, but the exact count doesn't matter
|
||||
assert!(n_crates > 20);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ mod process;
|
|||
|
||||
use paths::{AbsPath, AbsPathBuf};
|
||||
use span::Span;
|
||||
use std::{fmt, io, sync::Arc};
|
||||
use std::{fmt, io, sync::Arc, time::SystemTime};
|
||||
|
||||
use crate::{
|
||||
legacy_protocol::msg::{
|
||||
|
@ -66,6 +66,7 @@ pub struct ProcMacro {
|
|||
dylib_path: Arc<AbsPathBuf>,
|
||||
name: Box<str>,
|
||||
kind: ProcMacroKind,
|
||||
dylib_last_modified: Option<SystemTime>,
|
||||
}
|
||||
|
||||
impl Eq for ProcMacro {}
|
||||
|
@ -73,7 +74,8 @@ impl PartialEq for ProcMacro {
|
|||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
&& self.kind == other.kind
|
||||
&& Arc::ptr_eq(&self.dylib_path, &other.dylib_path)
|
||||
&& self.dylib_path == other.dylib_path
|
||||
&& self.dylib_last_modified == other.dylib_last_modified
|
||||
&& Arc::ptr_eq(&self.process, &other.process)
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +118,9 @@ impl ProcMacroClient {
|
|||
let macros = self.process.find_proc_macros(&dylib.path)?;
|
||||
|
||||
let dylib_path = Arc::new(dylib.path);
|
||||
let dylib_last_modified = std::fs::metadata(dylib_path.as_path())
|
||||
.ok()
|
||||
.and_then(|metadata| metadata.modified().ok());
|
||||
match macros {
|
||||
Ok(macros) => Ok(macros
|
||||
.into_iter()
|
||||
|
@ -124,6 +129,7 @@ impl ProcMacroClient {
|
|||
name: name.into(),
|
||||
kind,
|
||||
dylib_path: dylib_path.clone(),
|
||||
dylib_last_modified,
|
||||
})
|
||||
.collect()),
|
||||
Err(message) => Err(ServerError { message, io: None }),
|
||||
|
|
|
@ -12,7 +12,7 @@ fn test_derive_empty() {
|
|||
"DeriveEmpty",
|
||||
r#"struct S;"#,
|
||||
expect!["SUBTREE $$ 1 1"],
|
||||
expect!["SUBTREE $$ 42:2@0..100#2 42:2@0..100#2"],
|
||||
expect!["SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037"],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,12 @@ fn test_derive_error() {
|
|||
LITERAL Str #[derive(DeriveError)] struct S ; 1
|
||||
PUNCH ; [alone] 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT compile_error 42:2@0..100#2
|
||||
PUNCH ! [alone] 42:2@0..100#2
|
||||
SUBTREE () 42:2@0..100#2 42:2@0..100#2
|
||||
LITERAL Str #[derive(DeriveError)] struct S ; 42:2@0..100#2
|
||||
PUNCH ; [alone] 42:2@0..100#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT compile_error 42:2@0..100#4294967037
|
||||
PUNCH ! [alone] 42:2@0..100#4294967037
|
||||
SUBTREE () 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
LITERAL Str #[derive(DeriveError)] struct S ; 42:2@0..100#4294967037
|
||||
PUNCH ; [alone] 42:2@0..100#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -53,14 +53,14 @@ fn test_fn_like_macro_noop() {
|
|||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT ident 42:2@0..5#2
|
||||
PUNCH , [alone] 42:2@5..6#2
|
||||
LITERAL Integer 0 42:2@7..8#2
|
||||
PUNCH , [alone] 42:2@8..9#2
|
||||
LITERAL Integer 1 42:2@10..11#2
|
||||
PUNCH , [alone] 42:2@11..12#2
|
||||
SUBTREE [] 42:2@13..14#2 42:2@14..15#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT ident 42:2@0..5#4294967037
|
||||
PUNCH , [alone] 42:2@5..6#4294967037
|
||||
LITERAL Integer 0 42:2@7..8#4294967037
|
||||
PUNCH , [alone] 42:2@8..9#4294967037
|
||||
LITERAL Integer 1 42:2@10..11#4294967037
|
||||
PUNCH , [alone] 42:2@11..12#4294967037
|
||||
SUBTREE [] 42:2@13..14#4294967037 42:2@14..15#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -75,10 +75,10 @@ fn test_fn_like_macro_clone_ident_subtree() {
|
|||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT ident 42:2@0..5#2
|
||||
PUNCH , [alone] 42:2@5..6#2
|
||||
SUBTREE [] 42:2@7..8#2 42:2@7..8#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT ident 42:2@0..5#4294967037
|
||||
PUNCH , [alone] 42:2@5..6#4294967037
|
||||
SUBTREE [] 42:2@7..8#4294967037 42:2@7..8#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ fn test_fn_like_macro_clone_raw_ident() {
|
|||
SUBTREE $$ 1 1
|
||||
IDENT r#async 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT r#async 42:2@0..7#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT r#async 42:2@0..7#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,8 @@ fn test_fn_like_fn_like_span_join() {
|
|||
SUBTREE $$ 1 1
|
||||
IDENT r#joined 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT r#joined 42:2@0..11#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT r#joined 42:2@0..11#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,10 +121,10 @@ fn test_fn_like_fn_like_span_ops() {
|
|||
IDENT resolved_at_def_site 1
|
||||
IDENT start_span 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT set_def_site 41:1@0..150#2
|
||||
IDENT resolved_at_def_site 42:2@13..33#2
|
||||
IDENT start_span 42:2@34..34#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT set_def_site 41:1@0..150#4294967037
|
||||
IDENT resolved_at_def_site 42:2@13..33#4294967037
|
||||
IDENT start_span 42:2@34..34#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -143,14 +143,14 @@ fn test_fn_like_mk_literals() {
|
|||
LITERAL Integer 123i64 1
|
||||
LITERAL Integer 123 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
LITERAL ByteStr byte_string 42:2@0..100#2
|
||||
LITERAL Char c 42:2@0..100#2
|
||||
LITERAL Str string 42:2@0..100#2
|
||||
LITERAL Float 3.14f64 42:2@0..100#2
|
||||
LITERAL Float 3.14 42:2@0..100#2
|
||||
LITERAL Integer 123i64 42:2@0..100#2
|
||||
LITERAL Integer 123 42:2@0..100#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
LITERAL ByteStr byte_string 42:2@0..100#4294967037
|
||||
LITERAL Char c 42:2@0..100#4294967037
|
||||
LITERAL Str string 42:2@0..100#4294967037
|
||||
LITERAL Float 3.14f64 42:2@0..100#4294967037
|
||||
LITERAL Float 3.14 42:2@0..100#4294967037
|
||||
LITERAL Integer 123i64 42:2@0..100#4294967037
|
||||
LITERAL Integer 123 42:2@0..100#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -164,9 +164,9 @@ fn test_fn_like_mk_idents() {
|
|||
IDENT standard 1
|
||||
IDENT r#raw 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT standard 42:2@0..100#2
|
||||
IDENT r#raw 42:2@0..100#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT standard 42:2@0..100#4294967037
|
||||
IDENT r#raw 42:2@0..100#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -198,27 +198,27 @@ fn test_fn_like_macro_clone_literals() {
|
|||
PUNCH , [alone] 1
|
||||
LITERAL CStr null 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
LITERAL Integer 1u16 42:2@0..4#2
|
||||
PUNCH , [alone] 42:2@4..5#2
|
||||
LITERAL Integer 2_u32 42:2@6..11#2
|
||||
PUNCH , [alone] 42:2@11..12#2
|
||||
PUNCH - [alone] 42:2@13..14#2
|
||||
LITERAL Integer 4i64 42:2@14..18#2
|
||||
PUNCH , [alone] 42:2@18..19#2
|
||||
LITERAL Float 3.14f32 42:2@20..27#2
|
||||
PUNCH , [alone] 42:2@27..28#2
|
||||
LITERAL Str hello bridge 42:2@29..43#2
|
||||
PUNCH , [alone] 42:2@43..44#2
|
||||
LITERAL Str suffixedsuffix 42:2@45..61#2
|
||||
PUNCH , [alone] 42:2@61..62#2
|
||||
LITERAL StrRaw(2) raw 42:2@63..73#2
|
||||
PUNCH , [alone] 42:2@73..74#2
|
||||
LITERAL Char a 42:2@75..78#2
|
||||
PUNCH , [alone] 42:2@78..79#2
|
||||
LITERAL Byte b 42:2@80..84#2
|
||||
PUNCH , [alone] 42:2@84..85#2
|
||||
LITERAL CStr null 42:2@86..93#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
LITERAL Integer 1u16 42:2@0..4#4294967037
|
||||
PUNCH , [alone] 42:2@4..5#4294967037
|
||||
LITERAL Integer 2_u32 42:2@6..11#4294967037
|
||||
PUNCH , [alone] 42:2@11..12#4294967037
|
||||
PUNCH - [alone] 42:2@13..14#4294967037
|
||||
LITERAL Integer 4i64 42:2@14..18#4294967037
|
||||
PUNCH , [alone] 42:2@18..19#4294967037
|
||||
LITERAL Float 3.14f32 42:2@20..27#4294967037
|
||||
PUNCH , [alone] 42:2@27..28#4294967037
|
||||
LITERAL Str hello bridge 42:2@29..43#4294967037
|
||||
PUNCH , [alone] 42:2@43..44#4294967037
|
||||
LITERAL Str suffixedsuffix 42:2@45..61#4294967037
|
||||
PUNCH , [alone] 42:2@61..62#4294967037
|
||||
LITERAL StrRaw(2) raw 42:2@63..73#4294967037
|
||||
PUNCH , [alone] 42:2@73..74#4294967037
|
||||
LITERAL Char a 42:2@75..78#4294967037
|
||||
PUNCH , [alone] 42:2@78..79#4294967037
|
||||
LITERAL Byte b 42:2@80..84#4294967037
|
||||
PUNCH , [alone] 42:2@84..85#4294967037
|
||||
LITERAL CStr null 42:2@86..93#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -239,12 +239,12 @@ fn test_attr_macro() {
|
|||
LITERAL Str #[attr_error(some arguments)] mod m {} 1
|
||||
PUNCH ; [alone] 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#2 42:2@0..100#2
|
||||
IDENT compile_error 42:2@0..100#2
|
||||
PUNCH ! [alone] 42:2@0..100#2
|
||||
SUBTREE () 42:2@0..100#2 42:2@0..100#2
|
||||
LITERAL Str #[attr_error(some arguments)] mod m {} 42:2@0..100#2
|
||||
PUNCH ; [alone] 42:2@0..100#2"#]],
|
||||
SUBTREE $$ 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
IDENT compile_error 42:2@0..100#4294967037
|
||||
PUNCH ! [alone] 42:2@0..100#4294967037
|
||||
SUBTREE () 42:2@0..100#4294967037 42:2@0..100#4294967037
|
||||
LITERAL Str #[attr_error(some arguments)] mod m {} 42:2@0..100#4294967037
|
||||
PUNCH ; [alone] 42:2@0..100#4294967037"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -452,7 +452,7 @@ pub enum TargetKindData {
|
|||
}
|
||||
/// Identifies a crate by position in the crates array.
|
||||
///
|
||||
/// This will differ from `CrateId` when multiple `ProjectJson`
|
||||
/// This will differ from `Crate` when multiple `ProjectJson`
|
||||
/// workspaces are loaded.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
#[serde(transparent)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use base_db::{CrateGraph, ProcMacroPaths};
|
||||
use base_db::{CrateGraphBuilder, ProcMacroPaths};
|
||||
use cargo_metadata::Metadata;
|
||||
use cfg::{CfgAtom, CfgDiff};
|
||||
use expect_test::{expect_file, ExpectFile};
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||
Sysroot, WorkspaceBuildScripts,
|
||||
};
|
||||
|
||||
fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
||||
fn load_cargo(file: &str) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let project_workspace = load_workspace_from_metadata(file);
|
||||
to_crate_graph(project_workspace, &mut Default::default())
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ fn load_cargo(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
|||
fn load_cargo_with_overrides(
|
||||
file: &str,
|
||||
cfg_overrides: CfgOverrides,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let project_workspace =
|
||||
ProjectWorkspace { cfg_overrides, ..load_workspace_from_metadata(file) };
|
||||
to_crate_graph(project_workspace, &mut Default::default())
|
||||
|
@ -51,7 +51,7 @@ fn load_workspace_from_metadata(file: &str) -> ProjectWorkspace {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
|
||||
fn load_rust_project(file: &str) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let data = get_test_json_file(file);
|
||||
let project = rooted_project_json(data);
|
||||
let sysroot = get_fake_sysroot();
|
||||
|
@ -142,7 +142,7 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
|||
fn to_crate_graph(
|
||||
project_workspace: ProjectWorkspace,
|
||||
file_map: &mut FxHashMap<AbsPathBuf, FileId>,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
project_workspace.to_crate_graph(
|
||||
&mut {
|
||||
|path| {
|
||||
|
@ -154,7 +154,7 @@ fn to_crate_graph(
|
|||
)
|
||||
}
|
||||
|
||||
fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) {
|
||||
fn check_crate_graph(crate_graph: CrateGraphBuilder, expect: ExpectFile) {
|
||||
let mut crate_graph = format!("{crate_graph:#?}");
|
||||
|
||||
replace_root(&mut crate_graph, false);
|
||||
|
|
|
@ -6,8 +6,9 @@ use std::{collections::VecDeque, fmt, fs, iter, ops::Deref, sync, thread};
|
|||
|
||||
use anyhow::Context;
|
||||
use base_db::{
|
||||
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env,
|
||||
LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
|
||||
CrateBuilderId, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin,
|
||||
CrateWorkspaceData, DependencyBuilder, Env, LangCrateOrigin, ProcMacroPaths,
|
||||
TargetLayoutLoadResult,
|
||||
};
|
||||
use cfg::{CfgAtom, CfgDiff, CfgOptions};
|
||||
use intern::{sym, Symbol};
|
||||
|
@ -848,10 +849,14 @@ impl ProjectWorkspace {
|
|||
&self,
|
||||
load: FileLoader<'_>,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let _p = tracing::info_span!("ProjectWorkspace::to_crate_graph").entered();
|
||||
|
||||
let Self { kind, sysroot, cfg_overrides, rustc_cfg, .. } = self;
|
||||
let crate_ws_data = Arc::new(CrateWorkspaceData {
|
||||
toolchain: self.toolchain.clone(),
|
||||
data_layout: self.target_layout.clone(),
|
||||
});
|
||||
let (crate_graph, proc_macros) = match kind {
|
||||
ProjectWorkspaceKind::Json(project) => project_json_to_crate_graph(
|
||||
rustc_cfg.clone(),
|
||||
|
@ -861,6 +866,7 @@ impl ProjectWorkspace {
|
|||
extra_env,
|
||||
cfg_overrides,
|
||||
self.set_test,
|
||||
crate_ws_data,
|
||||
),
|
||||
ProjectWorkspaceKind::Cargo { cargo, rustc, build_scripts, error: _ } => {
|
||||
cargo_to_crate_graph(
|
||||
|
@ -872,6 +878,7 @@ impl ProjectWorkspace {
|
|||
cfg_overrides,
|
||||
build_scripts,
|
||||
self.set_test,
|
||||
crate_ws_data,
|
||||
)
|
||||
}
|
||||
ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => {
|
||||
|
@ -885,6 +892,7 @@ impl ProjectWorkspace {
|
|||
cfg_overrides,
|
||||
build_scripts,
|
||||
self.set_test,
|
||||
crate_ws_data,
|
||||
)
|
||||
} else {
|
||||
detached_file_to_crate_graph(
|
||||
|
@ -894,6 +902,7 @@ impl ProjectWorkspace {
|
|||
sysroot,
|
||||
cfg_overrides,
|
||||
self.set_test,
|
||||
crate_ws_data,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -959,15 +968,22 @@ fn project_json_to_crate_graph(
|
|||
extra_env: &FxHashMap<String, String>,
|
||||
override_cfg: &CfgOverrides,
|
||||
set_test: bool,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let mut res = (CrateGraphBuilder::default(), ProcMacroPaths::default());
|
||||
let (crate_graph, proc_macros) = &mut res;
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
let (public_deps, libproc_macro) = sysroot_to_crate_graph(
|
||||
crate_graph,
|
||||
sysroot,
|
||||
rustc_cfg.clone(),
|
||||
load,
|
||||
// FIXME: This looks incorrect but I don't think this matters.
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
|
||||
let mut cfg_cache: FxHashMap<&str, Vec<CfgAtom>> = FxHashMap::default();
|
||||
|
||||
let idx_to_crate_id: FxHashMap<CrateArrayIdx, CrateId> = project
|
||||
let idx_to_crate_id: FxHashMap<CrateArrayIdx, _> = project
|
||||
.crates()
|
||||
.filter_map(|(idx, krate)| Some((idx, krate, load(&krate.root_module)?)))
|
||||
.map(
|
||||
|
@ -1042,6 +1058,7 @@ fn project_json_to_crate_graph(
|
|||
},
|
||||
*is_proc_macro,
|
||||
proc_macro_cwd.clone(),
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
debug!(
|
||||
?crate_graph_crate_id,
|
||||
|
@ -1092,12 +1109,19 @@ fn cargo_to_crate_graph(
|
|||
override_cfg: &CfgOverrides,
|
||||
build_scripts: &WorkspaceBuildScripts,
|
||||
set_test: bool,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let _p = tracing::info_span!("cargo_to_crate_graph").entered();
|
||||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||
let mut res = (CrateGraphBuilder::default(), ProcMacroPaths::default());
|
||||
let (crate_graph, proc_macros) = &mut res;
|
||||
let (public_deps, libproc_macro) =
|
||||
sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
let (public_deps, libproc_macro) = sysroot_to_crate_graph(
|
||||
crate_graph,
|
||||
sysroot,
|
||||
rustc_cfg.clone(),
|
||||
load,
|
||||
// FIXME: This looks incorrect but I don't think this causes problems.
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
|
||||
let cfg_options = CfgOptions::from_iter(rustc_cfg);
|
||||
|
||||
|
@ -1163,6 +1187,7 @@ fn cargo_to_crate_graph(
|
|||
name: Symbol::intern(&pkg_data.name),
|
||||
}
|
||||
},
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
if let TargetKind::Lib { .. } = kind {
|
||||
lib_tgt = Some((crate_id, name.clone()));
|
||||
|
@ -1267,6 +1292,8 @@ fn cargo_to_crate_graph(
|
|||
} else {
|
||||
rustc_build_scripts
|
||||
},
|
||||
// FIXME: This looks incorrect but I don't think this causes problems.
|
||||
crate_ws_data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1280,11 +1307,18 @@ fn detached_file_to_crate_graph(
|
|||
sysroot: &Sysroot,
|
||||
override_cfg: &CfgOverrides,
|
||||
set_test: bool,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> (CrateGraphBuilder, ProcMacroPaths) {
|
||||
let _p = tracing::info_span!("detached_file_to_crate_graph").entered();
|
||||
let mut crate_graph = CrateGraph::default();
|
||||
let (public_deps, _libproc_macro) =
|
||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||
let mut crate_graph = CrateGraphBuilder::default();
|
||||
let (public_deps, _libproc_macro) = sysroot_to_crate_graph(
|
||||
&mut crate_graph,
|
||||
sysroot,
|
||||
rustc_cfg.clone(),
|
||||
load,
|
||||
// FIXME: This looks incorrect but I don't think this causes problems.
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
|
||||
let mut cfg_options = CfgOptions::from_iter(rustc_cfg);
|
||||
if set_test {
|
||||
|
@ -1316,6 +1350,7 @@ fn detached_file_to_crate_graph(
|
|||
},
|
||||
false,
|
||||
None,
|
||||
crate_ws_data,
|
||||
);
|
||||
|
||||
public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
|
||||
|
@ -1323,18 +1358,19 @@ fn detached_file_to_crate_graph(
|
|||
}
|
||||
|
||||
fn handle_rustc_crates(
|
||||
crate_graph: &mut CrateGraph,
|
||||
crate_graph: &mut CrateGraphBuilder,
|
||||
proc_macros: &mut ProcMacroPaths,
|
||||
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
|
||||
pkg_to_lib_crate: &mut FxHashMap<Package, CrateBuilderId>,
|
||||
load: FileLoader<'_>,
|
||||
rustc_workspace: &CargoWorkspace,
|
||||
cargo: &CargoWorkspace,
|
||||
public_deps: &SysrootPublicDeps,
|
||||
libproc_macro: Option<CrateId>,
|
||||
pkg_crates: &FxHashMap<Package, Vec<(CrateId, TargetKind)>>,
|
||||
libproc_macro: Option<CrateBuilderId>,
|
||||
pkg_crates: &FxHashMap<Package, Vec<(CrateBuilderId, TargetKind)>>,
|
||||
cfg_options: &CfgOptions,
|
||||
override_cfg: &CfgOverrides,
|
||||
build_scripts: &WorkspaceBuildScripts,
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) {
|
||||
let mut rustc_pkg_crates = FxHashMap::default();
|
||||
// The root package of the rustc-dev component is rustc_driver, so we match that
|
||||
|
@ -1377,6 +1413,7 @@ fn handle_rustc_crates(
|
|||
&rustc_workspace[tgt].name,
|
||||
kind,
|
||||
CrateOrigin::Rustc { name: Symbol::intern(&rustc_workspace[pkg].name) },
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||
// Add dependencies on core / std / alloc for this crate
|
||||
|
@ -1417,7 +1454,7 @@ fn handle_rustc_crates(
|
|||
// This avoids the situation where `from` depends on e.g. `arrayvec`, but
|
||||
// `rust_analyzer` thinks that it should use the one from the `rustc_source`
|
||||
// instead of the one from `crates.io`
|
||||
if !crate_graph[*from].dependencies.iter().any(|d| d.name == name) {
|
||||
if !crate_graph[*from].basic.dependencies.iter().any(|d| d.name == name) {
|
||||
add_dep(crate_graph, *from, name.clone(), to);
|
||||
}
|
||||
}
|
||||
|
@ -1427,7 +1464,7 @@ fn handle_rustc_crates(
|
|||
}
|
||||
|
||||
fn add_target_crate_root(
|
||||
crate_graph: &mut CrateGraph,
|
||||
crate_graph: &mut CrateGraphBuilder,
|
||||
proc_macros: &mut ProcMacroPaths,
|
||||
cargo: &CargoWorkspace,
|
||||
pkg: &PackageData,
|
||||
|
@ -1437,7 +1474,8 @@ fn add_target_crate_root(
|
|||
cargo_name: &str,
|
||||
kind: TargetKind,
|
||||
origin: CrateOrigin,
|
||||
) -> CrateId {
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> CrateBuilderId {
|
||||
let edition = pkg.edition;
|
||||
let potential_cfg_options = if pkg.features.is_empty() {
|
||||
None
|
||||
|
@ -1474,7 +1512,7 @@ fn add_target_crate_root(
|
|||
Some(CrateDisplayName::from_canonical_name(cargo_name)),
|
||||
Some(pkg.version.to_string()),
|
||||
Arc::new(cfg_options),
|
||||
potential_cfg_options.map(Arc::new),
|
||||
potential_cfg_options,
|
||||
env,
|
||||
origin,
|
||||
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
|
||||
|
@ -1483,6 +1521,7 @@ fn add_target_crate_root(
|
|||
} else {
|
||||
pkg.manifest.parent().to_path_buf()
|
||||
}),
|
||||
crate_ws_data,
|
||||
);
|
||||
if let TargetKind::Lib { is_proc_macro: true } = kind {
|
||||
let proc_macro = match build_data {
|
||||
|
@ -1503,12 +1542,12 @@ fn add_target_crate_root(
|
|||
|
||||
#[derive(Default, Debug)]
|
||||
struct SysrootPublicDeps {
|
||||
deps: Vec<(CrateName, CrateId, bool)>,
|
||||
deps: Vec<(CrateName, CrateBuilderId, bool)>,
|
||||
}
|
||||
|
||||
impl SysrootPublicDeps {
|
||||
/// Makes `from` depend on the public sysroot crates.
|
||||
fn add_to_crate_graph(&self, crate_graph: &mut CrateGraph, from: CrateId) {
|
||||
fn add_to_crate_graph(&self, crate_graph: &mut CrateGraphBuilder, from: CrateBuilderId) {
|
||||
for (name, krate, prelude) in &self.deps {
|
||||
add_dep_with_prelude(crate_graph, from, name.clone(), *krate, *prelude, true);
|
||||
}
|
||||
|
@ -1516,10 +1555,10 @@ impl SysrootPublicDeps {
|
|||
}
|
||||
|
||||
fn extend_crate_graph_with_sysroot(
|
||||
crate_graph: &mut CrateGraph,
|
||||
mut sysroot_crate_graph: CrateGraph,
|
||||
crate_graph: &mut CrateGraphBuilder,
|
||||
mut sysroot_crate_graph: CrateGraphBuilder,
|
||||
mut sysroot_proc_macros: ProcMacroPaths,
|
||||
) -> (SysrootPublicDeps, Option<CrateId>) {
|
||||
) -> (SysrootPublicDeps, Option<CrateBuilderId>) {
|
||||
let mut pub_deps = vec![];
|
||||
let mut libproc_macro = None;
|
||||
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]);
|
||||
|
@ -1527,11 +1566,11 @@ fn extend_crate_graph_with_sysroot(
|
|||
// uninject `test` flag so `core` keeps working.
|
||||
Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
|
||||
// patch the origin
|
||||
if c.origin.is_local() {
|
||||
if c.basic.origin.is_local() {
|
||||
let lang_crate = LangCrateOrigin::from(
|
||||
c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()),
|
||||
c.extra.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()),
|
||||
);
|
||||
c.origin = CrateOrigin::Lang(lang_crate);
|
||||
c.basic.origin = CrateOrigin::Lang(lang_crate);
|
||||
match lang_crate {
|
||||
LangCrateOrigin::Test
|
||||
| LangCrateOrigin::Alloc
|
||||
|
@ -1579,11 +1618,12 @@ fn extend_crate_graph_with_sysroot(
|
|||
}
|
||||
|
||||
fn sysroot_to_crate_graph(
|
||||
crate_graph: &mut CrateGraph,
|
||||
crate_graph: &mut CrateGraphBuilder,
|
||||
sysroot: &Sysroot,
|
||||
rustc_cfg: Vec<CfgAtom>,
|
||||
load: FileLoader<'_>,
|
||||
) -> (SysrootPublicDeps, Option<CrateId>) {
|
||||
crate_ws_data: Arc<CrateWorkspaceData>,
|
||||
) -> (SysrootPublicDeps, Option<CrateBuilderId>) {
|
||||
let _p = tracing::info_span!("sysroot_to_crate_graph").entered();
|
||||
match sysroot.workspace() {
|
||||
RustLibSrcWorkspace::Workspace(cargo) => {
|
||||
|
@ -1605,6 +1645,7 @@ fn sysroot_to_crate_graph(
|
|||
},
|
||||
&WorkspaceBuildScripts::default(),
|
||||
false,
|
||||
crate_ws_data,
|
||||
);
|
||||
|
||||
extend_crate_graph_with_sysroot(crate_graph, cg, pm)
|
||||
|
@ -1627,6 +1668,7 @@ fn sysroot_to_crate_graph(
|
|||
..Default::default()
|
||||
},
|
||||
false,
|
||||
crate_ws_data,
|
||||
);
|
||||
|
||||
extend_crate_graph_with_sysroot(crate_graph, cg, pm)
|
||||
|
@ -1639,29 +1681,31 @@ fn sysroot_to_crate_graph(
|
|||
cfg_options.insert_atom(sym::miri.clone());
|
||||
cfg_options
|
||||
});
|
||||
let sysroot_crates: FxHashMap<crate::sysroot::stitched::RustLibSrcCrate, CrateId> =
|
||||
stitched
|
||||
.crates()
|
||||
.filter_map(|krate| {
|
||||
let file_id = load(&stitched[krate].root)?;
|
||||
let sysroot_crates: FxHashMap<
|
||||
crate::sysroot::stitched::RustLibSrcCrate,
|
||||
CrateBuilderId,
|
||||
> = stitched
|
||||
.crates()
|
||||
.filter_map(|krate| {
|
||||
let file_id = load(&stitched[krate].root)?;
|
||||
|
||||
let display_name =
|
||||
CrateDisplayName::from_canonical_name(&stitched[krate].name);
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
file_id,
|
||||
Edition::CURRENT_FIXME,
|
||||
Some(display_name),
|
||||
None,
|
||||
cfg_options.clone(),
|
||||
None,
|
||||
Env::default(),
|
||||
CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
|
||||
false,
|
||||
None,
|
||||
);
|
||||
Some((krate, crate_id))
|
||||
})
|
||||
.collect();
|
||||
let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name);
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
file_id,
|
||||
Edition::CURRENT_FIXME,
|
||||
Some(display_name),
|
||||
None,
|
||||
cfg_options.clone(),
|
||||
None,
|
||||
Env::default(),
|
||||
CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
|
||||
false,
|
||||
None,
|
||||
crate_ws_data.clone(),
|
||||
);
|
||||
Some((krate, crate_id))
|
||||
})
|
||||
.collect();
|
||||
|
||||
for from in stitched.crates() {
|
||||
for &to in stitched[from].deps.iter() {
|
||||
|
@ -1691,22 +1735,32 @@ fn sysroot_to_crate_graph(
|
|||
}
|
||||
}
|
||||
|
||||
fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) {
|
||||
add_dep_inner(graph, from, Dependency::new(name, to))
|
||||
fn add_dep(
|
||||
graph: &mut CrateGraphBuilder,
|
||||
from: CrateBuilderId,
|
||||
name: CrateName,
|
||||
to: CrateBuilderId,
|
||||
) {
|
||||
add_dep_inner(graph, from, DependencyBuilder::new(name, to))
|
||||
}
|
||||
|
||||
fn add_dep_with_prelude(
|
||||
graph: &mut CrateGraph,
|
||||
from: CrateId,
|
||||
graph: &mut CrateGraphBuilder,
|
||||
from: CrateBuilderId,
|
||||
name: CrateName,
|
||||
to: CrateId,
|
||||
to: CrateBuilderId,
|
||||
prelude: bool,
|
||||
sysroot: bool,
|
||||
) {
|
||||
add_dep_inner(graph, from, Dependency::with_prelude(name, to, prelude, sysroot))
|
||||
add_dep_inner(graph, from, DependencyBuilder::with_prelude(name, to, prelude, sysroot))
|
||||
}
|
||||
|
||||
fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId, prelude: bool) {
|
||||
fn add_proc_macro_dep(
|
||||
crate_graph: &mut CrateGraphBuilder,
|
||||
from: CrateBuilderId,
|
||||
to: CrateBuilderId,
|
||||
prelude: bool,
|
||||
) {
|
||||
add_dep_with_prelude(
|
||||
crate_graph,
|
||||
from,
|
||||
|
@ -1717,7 +1771,7 @@ fn add_proc_macro_dep(crate_graph: &mut CrateGraph, from: CrateId, to: CrateId,
|
|||
);
|
||||
}
|
||||
|
||||
fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {
|
||||
fn add_dep_inner(graph: &mut CrateGraphBuilder, from: CrateBuilderId, dep: DependencyBuilder) {
|
||||
if let Err(err) = graph.add_dep(from, dep) {
|
||||
tracing::warn!("{}", err)
|
||||
}
|
||||
|
|
|
@ -1,20 +1,47 @@
|
|||
{
|
||||
0: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
0: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -22,7 +49,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -44,45 +70,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
1: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
1: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -90,7 +135,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -112,53 +156,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
2: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
2: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -166,7 +221,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -188,53 +242,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
3: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
3: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -242,7 +307,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -264,53 +328,60 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
4: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
name: "libc",
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
4: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"feature=default",
|
||||
|
@ -318,20 +389,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
),
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -353,18 +410,11 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
name: "libc",
|
||||
toolchain: None,
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -1,20 +1,47 @@
|
|||
{
|
||||
0: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
0: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -22,7 +49,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -44,45 +70,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
1: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
1: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -90,7 +135,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -112,53 +156,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
2: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
2: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -166,7 +221,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -188,53 +242,64 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
3: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
3: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
|
@ -242,7 +307,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -264,53 +328,60 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
4: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
name: "libc",
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
4: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"feature=default",
|
||||
|
@ -318,20 +389,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
),
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -353,18 +410,11 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
name: "libc",
|
||||
toolchain: None,
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -1,27 +1,53 @@
|
|||
{
|
||||
0: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
0: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
1,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -43,52 +69,70 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
1: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
1: CrateData {
|
||||
root_file_id: FileId(
|
||||
2,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
canonical_name: "hello-world",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -110,60 +154,70 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
2: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
2: CrateData {
|
||||
root_file_id: FileId(
|
||||
3,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"an_example",
|
||||
),
|
||||
canonical_name: "an-example",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -185,60 +239,70 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
3: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateBuilder>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
),
|
||||
},
|
||||
3: CrateData {
|
||||
root_file_id: FileId(
|
||||
4,
|
||||
),
|
||||
edition: Edition2018,
|
||||
version: Some(
|
||||
"0.1.0",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"it",
|
||||
),
|
||||
canonical_name: "it",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"rust_analyzer",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: None,
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -260,53 +324,60 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(0),
|
||||
name: CrateName(
|
||||
"hello_world",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
toolchain: None,
|
||||
},
|
||||
},
|
||||
4: CrateBuilder {
|
||||
basic: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
name: "libc",
|
||||
},
|
||||
Dependency {
|
||||
crate_id: Idx::<CrateData>(4),
|
||||
name: CrateName(
|
||||
"libc",
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
prelude: true,
|
||||
sysroot: false,
|
||||
},
|
||||
],
|
||||
origin: Local {
|
||||
repo: None,
|
||||
name: Some(
|
||||
"hello-world",
|
||||
),
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$hello-world",
|
||||
extra: ExtraCrateData {
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
4: CrateData {
|
||||
root_file_id: FileId(
|
||||
5,
|
||||
),
|
||||
edition: Edition2015,
|
||||
version: Some(
|
||||
"0.2.98",
|
||||
),
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
display_name: Some(
|
||||
CrateDisplayName {
|
||||
crate_name: CrateName(
|
||||
"libc",
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
canonical_name: "libc",
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
cfg_options: CfgOptions(
|
||||
[
|
||||
"feature=default",
|
||||
|
@ -314,20 +385,6 @@
|
|||
"true",
|
||||
],
|
||||
),
|
||||
potential_cfg_options: Some(
|
||||
CfgOptions(
|
||||
[
|
||||
"feature=align",
|
||||
"feature=const-extern-fn",
|
||||
"feature=default",
|
||||
"feature=extra_traits",
|
||||
"feature=rustc-dep-of-std",
|
||||
"feature=std",
|
||||
"feature=use_std",
|
||||
"true",
|
||||
],
|
||||
),
|
||||
),
|
||||
env: Env {
|
||||
entries: {
|
||||
"CARGO": "$CARGO$",
|
||||
|
@ -349,18 +406,11 @@
|
|||
"CARGO_PKG_VERSION_PRE": "",
|
||||
},
|
||||
},
|
||||
dependencies: [],
|
||||
origin: Library {
|
||||
repo: Some(
|
||||
"https://github.com/rust-lang/libc",
|
||||
ws_data: CrateWorkspaceData {
|
||||
data_layout: Err(
|
||||
"target_data_layout not loaded",
|
||||
),
|
||||
name: "libc",
|
||||
toolchain: None,
|
||||
},
|
||||
is_proc_macro: false,
|
||||
proc_macro_cwd: Some(
|
||||
AbsPathBuf(
|
||||
"$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98",
|
||||
),
|
||||
),
|
||||
},
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue