mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	fix: Make lang items query properly filter out overwritten/excluded sysroots
This commit is contained in:
		
							parent
							
								
									e10fa9393e
								
							
						
					
					
						commit
						15ac6a21dd
					
				
					 7 changed files with 167 additions and 69 deletions
				
			
		| 
						 | 
					@ -30,6 +30,8 @@ use triomphe::Arc;
 | 
				
			||||||
pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet};
 | 
					pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type FxIndexSet<T> = indexmap::IndexSet<T, rustc_hash::FxBuildHasher>;
 | 
					pub type FxIndexSet<T> = indexmap::IndexSet<T, rustc_hash::FxBuildHasher>;
 | 
				
			||||||
 | 
					pub type FxIndexMap<K, V> =
 | 
				
			||||||
 | 
					    indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[macro_export]
 | 
					#[macro_export]
 | 
				
			||||||
macro_rules! impl_intern_key {
 | 
					macro_rules! impl_intern_key {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ use crate::{
 | 
				
			||||||
    StaticId, StructId, TraitId, TypeAliasId, UnionId,
 | 
					    StaticId, StructId, TraitId, TypeAliasId, UnionId,
 | 
				
			||||||
    db::DefDatabase,
 | 
					    db::DefDatabase,
 | 
				
			||||||
    expr_store::path::Path,
 | 
					    expr_store::path::Path,
 | 
				
			||||||
    nameres::{assoc::TraitItems, crate_def_map},
 | 
					    nameres::{assoc::TraitItems, crate_def_map, crate_local_def_map},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 | 
				
			||||||
| 
						 | 
					@ -170,7 +170,19 @@ pub fn lang_item(
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return Some(target);
 | 
					        return Some(target);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    start_crate.data(db).dependencies.iter().find_map(|dep| lang_item(db, dep.crate_id, item))
 | 
					
 | 
				
			||||||
 | 
					    // Our `CrateGraph` eagerly inserts sysroot dependencies like `core` or `std` into dependencies
 | 
				
			||||||
 | 
					    // even if the target crate has `#![no_std]`, `#![no_core]` or shadowed sysroot dependencies
 | 
				
			||||||
 | 
					    // like `dependencies.std.path = ".."`. So we use `extern_prelude()` instead of
 | 
				
			||||||
 | 
					    // `CrateData.dependencies` here, which has already come through such sysroot complexities
 | 
				
			||||||
 | 
					    // while nameres.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // See https://github.com/rust-lang/rust-analyzer/pull/20475 for details.
 | 
				
			||||||
 | 
					    crate_local_def_map(db, start_crate).local(db).extern_prelude().find_map(|(_, (krate, _))| {
 | 
				
			||||||
 | 
					        // Some crates declares themselves as extern crate like `extern crate self as core`.
 | 
				
			||||||
 | 
					        // Ignore these to prevent cycles.
 | 
				
			||||||
 | 
					        if krate.krate == start_crate { None } else { lang_item(db, krate.krate, item) }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Default, Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -545,6 +545,10 @@ impl DefMap {
 | 
				
			||||||
        self.data.no_std || self.data.no_core
 | 
					        self.data.no_std || self.data.no_core
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn is_no_core(&self) -> bool {
 | 
				
			||||||
 | 
					        self.data.no_core
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
 | 
					    pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
 | 
				
			||||||
        self.data.fn_proc_macro_mapping.get(&id).copied()
 | 
					        self.data.fn_proc_macro_mapping.get(&id).copied()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,11 @@ use triomphe::Arc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc,
 | 
					    AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc,
 | 
				
			||||||
    ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId,
 | 
					    ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, FxIndexMap, ImplLoc, Intern,
 | 
				
			||||||
    LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
 | 
					    ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
 | 
				
			||||||
    MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
 | 
					    MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId,
 | 
				
			||||||
    StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
 | 
					    ProcMacroLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId,
 | 
				
			||||||
 | 
					    UseLoc,
 | 
				
			||||||
    attr::Attrs,
 | 
					    attr::Attrs,
 | 
				
			||||||
    db::DefDatabase,
 | 
					    db::DefDatabase,
 | 
				
			||||||
    item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports},
 | 
					    item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports},
 | 
				
			||||||
| 
						 | 
					@ -69,7 +70,7 @@ pub(super) fn collect_defs(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // populate external prelude and dependency list
 | 
					    // populate external prelude and dependency list
 | 
				
			||||||
    let mut deps =
 | 
					    let mut deps =
 | 
				
			||||||
        FxHashMap::with_capacity_and_hasher(krate.dependencies.len(), Default::default());
 | 
					        FxIndexMap::with_capacity_and_hasher(krate.dependencies.len(), Default::default());
 | 
				
			||||||
    for dep in &krate.dependencies {
 | 
					    for dep in &krate.dependencies {
 | 
				
			||||||
        tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
 | 
					        tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,7 +221,7 @@ struct DefCollector<'db> {
 | 
				
			||||||
    /// Set only in case of blocks.
 | 
					    /// Set only in case of blocks.
 | 
				
			||||||
    crate_local_def_map: Option<&'db LocalDefMap>,
 | 
					    crate_local_def_map: Option<&'db LocalDefMap>,
 | 
				
			||||||
    // The dependencies of the current crate, including optional deps like `test`.
 | 
					    // The dependencies of the current crate, including optional deps like `test`.
 | 
				
			||||||
    deps: FxHashMap<Name, BuiltDependency>,
 | 
					    deps: FxIndexMap<Name, BuiltDependency>,
 | 
				
			||||||
    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
 | 
					    glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
 | 
				
			||||||
    unresolved_imports: Vec<ImportDirective>,
 | 
					    unresolved_imports: Vec<ImportDirective>,
 | 
				
			||||||
    indeterminate_imports: Vec<(ImportDirective, PerNs)>,
 | 
					    indeterminate_imports: Vec<(ImportDirective, PerNs)>,
 | 
				
			||||||
| 
						 | 
					@ -332,7 +333,9 @@ impl<'db> DefCollector<'db> {
 | 
				
			||||||
                let skip = dep.is_sysroot()
 | 
					                let skip = dep.is_sysroot()
 | 
				
			||||||
                    && match dep.crate_id.data(self.db).origin {
 | 
					                    && match dep.crate_id.data(self.db).origin {
 | 
				
			||||||
                        CrateOrigin::Lang(LangCrateOrigin::Core) => crate_data.no_core,
 | 
					                        CrateOrigin::Lang(LangCrateOrigin::Core) => crate_data.no_core,
 | 
				
			||||||
                        CrateOrigin::Lang(LangCrateOrigin::Std) => crate_data.no_std,
 | 
					                        CrateOrigin::Lang(LangCrateOrigin::Std) => {
 | 
				
			||||||
 | 
					                            crate_data.no_core || crate_data.no_std
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        _ => false,
 | 
					                        _ => false,
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                if skip {
 | 
					                if skip {
 | 
				
			||||||
| 
						 | 
					@ -2550,7 +2553,7 @@ mod tests {
 | 
				
			||||||
            def_map,
 | 
					            def_map,
 | 
				
			||||||
            local_def_map: LocalDefMap::default(),
 | 
					            local_def_map: LocalDefMap::default(),
 | 
				
			||||||
            crate_local_def_map: None,
 | 
					            crate_local_def_map: None,
 | 
				
			||||||
            deps: FxHashMap::default(),
 | 
					            deps: FxIndexMap::default(),
 | 
				
			||||||
            glob_imports: FxHashMap::default(),
 | 
					            glob_imports: FxHashMap::default(),
 | 
				
			||||||
            unresolved_imports: Vec::new(),
 | 
					            unresolved_imports: Vec::new(),
 | 
				
			||||||
            indeterminate_imports: Vec::new(),
 | 
					            indeterminate_imports: Vec::new(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2388,3 +2388,54 @@ pub trait Destruct {}
 | 
				
			||||||
"#,
 | 
					"#,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn no_duplicated_lang_item_metadata() {
 | 
				
			||||||
 | 
					    check_types(
 | 
				
			||||||
 | 
					        r#"
 | 
				
			||||||
 | 
					//- minicore: pointee
 | 
				
			||||||
 | 
					//- /main.rs crate:main deps:std,core
 | 
				
			||||||
 | 
					use std::AtomicPtr;
 | 
				
			||||||
 | 
					use std::null_mut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let x: AtomicPtr<()> = AtomicPtr::new(null_mut());
 | 
				
			||||||
 | 
					      //^ AtomicPtr<()>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//- /lib.rs crate:r#std deps:core
 | 
				
			||||||
 | 
					#![no_std]
 | 
				
			||||||
 | 
					pub use core::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//- /lib.rs crate:r#core
 | 
				
			||||||
 | 
					#![no_core]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[lang = "pointee_trait"]
 | 
				
			||||||
 | 
					pub trait Pointee {
 | 
				
			||||||
 | 
					    #[lang = "metadata_type"]
 | 
				
			||||||
 | 
					    type Metadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct AtomicPtr<T>(T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<T> AtomicPtr<T> {
 | 
				
			||||||
 | 
					    pub fn new(p: *mut T) -> AtomicPtr<T> {
 | 
				
			||||||
 | 
					        loop {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[lang = "pointee_sized"]
 | 
				
			||||||
 | 
					pub trait PointeeSized {}
 | 
				
			||||||
 | 
					#[lang = "meta_sized"]
 | 
				
			||||||
 | 
					pub trait MetaSized: PointeeSized {}
 | 
				
			||||||
 | 
					#[lang = "sized"]
 | 
				
			||||||
 | 
					pub trait Sized: MetaSized {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub trait Thin = Pointee<Metadata = ()> + PointeeSized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn null_mut<T: PointeeSized + Thin>() -> *mut T {
 | 
				
			||||||
 | 
					    loop {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					"#,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,13 +66,9 @@ pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
 | 
				
			||||||
pub use ::line_index;
 | 
					pub use ::line_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience.
 | 
					/// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience.
 | 
				
			||||||
pub use base_db;
 | 
					pub use base_db::{self, FxIndexMap, FxIndexSet};
 | 
				
			||||||
pub use span::{self, FileId};
 | 
					pub use span::{self, FileId};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type FxIndexSet<T> = indexmap::IndexSet<T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 | 
					 | 
				
			||||||
pub type FxIndexMap<K, V> =
 | 
					 | 
				
			||||||
    indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub type FilePosition = FilePositionWrapper<FileId>;
 | 
					pub type FilePosition = FilePositionWrapper<FileId>;
 | 
				
			||||||
pub type FileRange = FileRangeWrapper<FileId>;
 | 
					pub type FileRange = FileRangeWrapper<FileId>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@ use std::{any::TypeId, mem, str::FromStr, sync};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use base_db::{
 | 
					use base_db::{
 | 
				
			||||||
    Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData,
 | 
					    Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData,
 | 
				
			||||||
    DependencyBuilder, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabase, SourceRoot,
 | 
					    DependencyBuilder, Env, FileChange, FileSet, FxIndexMap, LangCrateOrigin, SourceDatabase,
 | 
				
			||||||
    Version, VfsPath, salsa,
 | 
					    SourceRoot, Version, VfsPath, salsa,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use cfg::CfgOptions;
 | 
					use cfg::CfgOptions;
 | 
				
			||||||
use hir_expand::{
 | 
					use hir_expand::{
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,6 @@ use hir_expand::{
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use intern::{Symbol, sym};
 | 
					use intern::{Symbol, sym};
 | 
				
			||||||
use paths::AbsPathBuf;
 | 
					use paths::AbsPathBuf;
 | 
				
			||||||
use rustc_hash::FxHashMap;
 | 
					 | 
				
			||||||
use span::{Edition, FileId, Span};
 | 
					use span::{Edition, FileId, Span};
 | 
				
			||||||
use stdx::itertools::Itertools;
 | 
					use stdx::itertools::Itertools;
 | 
				
			||||||
use test_utils::{
 | 
					use test_utils::{
 | 
				
			||||||
| 
						 | 
					@ -147,7 +146,7 @@ impl ChangeFixture {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut files = Vec::new();
 | 
					        let mut files = Vec::new();
 | 
				
			||||||
        let mut crate_graph = CrateGraphBuilder::default();
 | 
					        let mut crate_graph = CrateGraphBuilder::default();
 | 
				
			||||||
        let mut crates = FxHashMap::default();
 | 
					        let mut crates = FxIndexMap::default();
 | 
				
			||||||
        let mut crate_deps = Vec::new();
 | 
					        let mut crate_deps = Vec::new();
 | 
				
			||||||
        let mut default_crate_root: Option<FileId> = None;
 | 
					        let mut default_crate_root: Option<FileId> = None;
 | 
				
			||||||
        let mut default_edition = Edition::CURRENT;
 | 
					        let mut default_edition = Edition::CURRENT;
 | 
				
			||||||
| 
						 | 
					@ -249,37 +248,7 @@ impl ChangeFixture {
 | 
				
			||||||
            file_id = FileId::from_raw(file_id.index() + 1);
 | 
					            file_id = FileId::from_raw(file_id.index() + 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if crates.is_empty() {
 | 
					        let mini_core = mini_core.map(|mini_core| {
 | 
				
			||||||
            let crate_root = default_crate_root
 | 
					 | 
				
			||||||
                .expect("missing default crate root, specify a main.rs or lib.rs");
 | 
					 | 
				
			||||||
            crate_graph.add_crate_root(
 | 
					 | 
				
			||||||
                crate_root,
 | 
					 | 
				
			||||||
                default_edition,
 | 
					 | 
				
			||||||
                Some(CrateName::new("ra_test_fixture").unwrap().into()),
 | 
					 | 
				
			||||||
                None,
 | 
					 | 
				
			||||||
                default_cfg.clone(),
 | 
					 | 
				
			||||||
                Some(default_cfg),
 | 
					 | 
				
			||||||
                default_env,
 | 
					 | 
				
			||||||
                CrateOrigin::Local { repo: None, name: None },
 | 
					 | 
				
			||||||
                false,
 | 
					 | 
				
			||||||
                proc_macro_cwd.clone(),
 | 
					 | 
				
			||||||
                crate_ws_data.clone(),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            for (from, to, prelude) in crate_deps {
 | 
					 | 
				
			||||||
                let from_id = crates[&from];
 | 
					 | 
				
			||||||
                let to_id = crates[&to];
 | 
					 | 
				
			||||||
                let sysroot = crate_graph[to_id].basic.origin.is_lang();
 | 
					 | 
				
			||||||
                crate_graph
 | 
					 | 
				
			||||||
                    .add_dep(
 | 
					 | 
				
			||||||
                        from_id,
 | 
					 | 
				
			||||||
                        DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot),
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    .unwrap();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if let Some(mini_core) = mini_core {
 | 
					 | 
				
			||||||
            let core_file = file_id;
 | 
					            let core_file = file_id;
 | 
				
			||||||
            file_id = FileId::from_raw(file_id.index() + 1);
 | 
					            file_id = FileId::from_raw(file_id.index() + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,8 +258,6 @@ impl ChangeFixture {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            source_change.change_file(core_file, Some(mini_core.source_code()));
 | 
					            source_change.change_file(core_file, Some(mini_core.source_code()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let all_crates = crate_graph.iter().collect::<Vec<_>>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let core_crate = crate_graph.add_crate_root(
 | 
					            let core_crate = crate_graph.add_crate_root(
 | 
				
			||||||
                core_file,
 | 
					                core_file,
 | 
				
			||||||
                Edition::CURRENT,
 | 
					                Edition::CURRENT,
 | 
				
			||||||
| 
						 | 
					@ -308,16 +275,58 @@ impl ChangeFixture {
 | 
				
			||||||
                crate_ws_data.clone(),
 | 
					                crate_ws_data.clone(),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for krate in all_crates {
 | 
					            (
 | 
				
			||||||
                crate_graph
 | 
					                move || {
 | 
				
			||||||
                    .add_dep(
 | 
					 | 
				
			||||||
                        krate,
 | 
					 | 
				
			||||||
                    DependencyBuilder::with_prelude(
 | 
					                    DependencyBuilder::with_prelude(
 | 
				
			||||||
                        CrateName::new("core").unwrap(),
 | 
					                        CrateName::new("core").unwrap(),
 | 
				
			||||||
                        core_crate,
 | 
					                        core_crate,
 | 
				
			||||||
                        true,
 | 
					                        true,
 | 
				
			||||||
                        true,
 | 
					                        true,
 | 
				
			||||||
                        ),
 | 
					                    )
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                core_crate,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if crates.is_empty() {
 | 
				
			||||||
 | 
					            let crate_root = default_crate_root
 | 
				
			||||||
 | 
					                .expect("missing default crate root, specify a main.rs or lib.rs");
 | 
				
			||||||
 | 
					            let root = crate_graph.add_crate_root(
 | 
				
			||||||
 | 
					                crate_root,
 | 
				
			||||||
 | 
					                default_edition,
 | 
				
			||||||
 | 
					                Some(CrateName::new("ra_test_fixture").unwrap().into()),
 | 
				
			||||||
 | 
					                None,
 | 
				
			||||||
 | 
					                default_cfg.clone(),
 | 
				
			||||||
 | 
					                Some(default_cfg),
 | 
				
			||||||
 | 
					                default_env,
 | 
				
			||||||
 | 
					                CrateOrigin::Local { repo: None, name: None },
 | 
				
			||||||
 | 
					                false,
 | 
				
			||||||
 | 
					                proc_macro_cwd.clone(),
 | 
				
			||||||
 | 
					                crate_ws_data.clone(),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            if let Some((mini_core, _)) = mini_core {
 | 
				
			||||||
 | 
					                crate_graph.add_dep(root, mini_core()).unwrap();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // Insert minicore first to match with `project-model::workspace`
 | 
				
			||||||
 | 
					            if let Some((mini_core, core_crate)) = mini_core {
 | 
				
			||||||
 | 
					                let all_crates = crate_graph.iter().collect::<Vec<_>>();
 | 
				
			||||||
 | 
					                for krate in all_crates {
 | 
				
			||||||
 | 
					                    if krate == core_crate {
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    crate_graph.add_dep(krate, mini_core()).unwrap();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (from, to, prelude) in crate_deps {
 | 
				
			||||||
 | 
					                let from_id = crates[&from];
 | 
				
			||||||
 | 
					                let to_id = crates[&to];
 | 
				
			||||||
 | 
					                let sysroot = crate_graph[to_id].basic.origin.is_lang();
 | 
				
			||||||
 | 
					                crate_graph
 | 
				
			||||||
 | 
					                    .add_dep(
 | 
				
			||||||
 | 
					                        from_id,
 | 
				
			||||||
 | 
					                        DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot),
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    .unwrap();
 | 
					                    .unwrap();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -627,11 +636,23 @@ impl FileMeta {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
				
			||||||
 | 
					enum ForceNoneLangOrigin {
 | 
				
			||||||
 | 
					    Yes,
 | 
				
			||||||
 | 
					    No,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn parse_crate(
 | 
					fn parse_crate(
 | 
				
			||||||
    crate_str: String,
 | 
					    crate_str: String,
 | 
				
			||||||
    current_source_root_kind: SourceRootKind,
 | 
					    current_source_root_kind: SourceRootKind,
 | 
				
			||||||
    explicit_non_workspace_member: bool,
 | 
					    explicit_non_workspace_member: bool,
 | 
				
			||||||
) -> (String, CrateOrigin, Option<String>) {
 | 
					) -> (String, CrateOrigin, Option<String>) {
 | 
				
			||||||
 | 
					    let (crate_str, force_non_lang_origin) = if let Some(s) = crate_str.strip_prefix("r#") {
 | 
				
			||||||
 | 
					        (s.to_owned(), ForceNoneLangOrigin::Yes)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        (crate_str, ForceNoneLangOrigin::No)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // syntax:
 | 
					    // syntax:
 | 
				
			||||||
    //   "my_awesome_crate"
 | 
					    //   "my_awesome_crate"
 | 
				
			||||||
    //   "my_awesome_crate@0.0.1,http://example.com"
 | 
					    //   "my_awesome_crate@0.0.1,http://example.com"
 | 
				
			||||||
| 
						 | 
					@ -646,7 +667,15 @@ fn parse_crate(
 | 
				
			||||||
    let non_workspace_member = explicit_non_workspace_member
 | 
					    let non_workspace_member = explicit_non_workspace_member
 | 
				
			||||||
        || matches!(current_source_root_kind, SourceRootKind::Library);
 | 
					        || matches!(current_source_root_kind, SourceRootKind::Library);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let origin = match LangCrateOrigin::from(&*name) {
 | 
					    let origin = if force_non_lang_origin == ForceNoneLangOrigin::Yes {
 | 
				
			||||||
 | 
					        let name = Symbol::intern(&name);
 | 
				
			||||||
 | 
					        if non_workspace_member {
 | 
				
			||||||
 | 
					            CrateOrigin::Library { repo, name }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            CrateOrigin::Local { repo, name: Some(name) }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        match LangCrateOrigin::from(&*name) {
 | 
				
			||||||
            LangCrateOrigin::Other => {
 | 
					            LangCrateOrigin::Other => {
 | 
				
			||||||
                let name = Symbol::intern(&name);
 | 
					                let name = Symbol::intern(&name);
 | 
				
			||||||
                if non_workspace_member {
 | 
					                if non_workspace_member {
 | 
				
			||||||
| 
						 | 
					@ -656,6 +685,7 @@ fn parse_crate(
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            origin => CrateOrigin::Lang(origin),
 | 
					            origin => CrateOrigin::Lang(origin),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (name, origin, version)
 | 
					    (name, origin, version)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue