Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lang_item.rs')
-rw-r--r--crates/hir-def/src/lang_item.rs16
1 files changed, 14 insertions, 2 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index a0be69cb2f..600f206770 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -12,7 +12,7 @@ use crate::{
StaticId, StructId, TraitId, TypeAliasId, UnionId,
db::DefDatabase,
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)]
@@ -170,7 +170,19 @@ pub fn lang_item(
{
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)]